Sfoglia il codice sorgente

Implements the possibility to switch between different Fairness Models

Options -> FairnessModel to switch it
Currently implemented:
-minimum demand first
-everyone the same amount of energy
Andreas T. Meyer-Berg 6 anni fa
parent
commit
01c0351426

+ 8 - 0
src/ui/controller/Control.java

@@ -977,5 +977,13 @@ public class Control {
 	public void setShowSupplyBars(boolean showSupplyBars) {
 		globalController.setShowSupplyBars(showSupplyBars);
 	}
+	
+	/**
+     * Sets fairness Model
+     * @param fairnessModel that should be used. 
+     */
+	public void setFairnessModel(short fairnessModel) {
+		globalController.setFairnessModel(fairnessModel);
+	}
 
 }

+ 8 - 0
src/ui/controller/GlobalController.java

@@ -172,4 +172,12 @@ public class GlobalController {
 	public void setShowSupplyBars(boolean showSupplyBars) {
 		model.setShowSupplyBars(showSupplyBars);
 	}
+	
+	/**
+	 * sets showSupplyBars
+	 * @param showSupplyBars
+	 */
+	public void setFairnessModel(short fairnessModel) {
+		model.setFairnessModel(fairnessModel);
+	}
 }

+ 868 - 724
src/ui/controller/SimulationManager.java

@@ -17,729 +17,873 @@ import java.util.HashMap;
  * @author Gruppe14
  */
 public class SimulationManager {
-    int global = 0;
-    private Model model;
-    private ArrayList<AbstractCpsObject> objectsToHandle;
-    //	private ArrayList<CpsEdge> allConnections;
-    private ArrayList<SubNet> subNets;
-    private ArrayList<CpsEdge> brokenEdges;
-    private MyCanvas canvas;
-    private int timeStep;
-    private HashMap<Integer, Float> tagTable = new HashMap<>();
-    private FlexiblePane flexPane;
-
-    private HashMap<HolonElement, Float> flexDevicesTurnedOnThisTurn = new HashMap<>();
-
-    /**
-     * Constructor.
-     *
-     * @param m Model
-     */
-    SimulationManager(Model m) {
-        canvas = null;
-        model = m;
-        subNets = new ArrayList<>();
-        brokenEdges = new ArrayList<>();
-    }
-
-    /**
-     * calculates the flow of the edges and the supply for objects.
-     *
-     * @param x current Iteration
-     */
-    void calculateStateForTimeStep(int x) {
-        reset();
-        timeStep = x;
-        searchForSubNets();
-        for (SubNet singleSubNet : subNets) {
-            resetConnections(singleSubNet.getObjects().get(0), new ArrayList<>(), new ArrayList<>());
-        }
-        for (SubNet singleSubNet : subNets) {
-            float production = calculateEnergyWithoutFlexDevices("prod", singleSubNet, timeStep);
-            float consumption = calculateEnergyWithoutFlexDevices("cons", singleSubNet, timeStep);
-            // surplus of energy is computed by sum, since consumption is a negative value
-            float energySurplus = production + consumption;
-
-            float minConsumption = calculateMinimumEnergy(singleSubNet, timeStep);
-
-            // --------------- use flexible devices ---------------
-            if (energySurplus != 0 && model.useFlexibleDevices()) {
-                turnOnFlexibleDevices(singleSubNet, energySurplus, x);
-
-//                if (!flexDevicesTurnedOnThisTurn.isEmpty()) {
-//                    System.out.println("The following devices were turned on in this turn: ");
-//                    System.out.println(flexDevicesTurnedOnThisTurn.toString());
-//                }
-
-                // recompute after having examined/turned on all flexible devices
-                production = calculateEnergyWithFlexDevices("prod", singleSubNet, timeStep);
-                consumption = calculateEnergyWithFlexDevices("cons", singleSubNet, timeStep);
-                energySurplus = production + consumption;
-            }
-
-            // --------------- set flow simulation ---------------
-            setFlowSimulation(singleSubNet);
-
-            // --------------- visualise graph ---------------
-           
-            
-            /**
-             * production of subnets, that might be partially turned on/off
-             */
-            float currentProduction = production;
-            /**
-             * HolonObjects that can be partially Supplied but might be fully Supplied
-             */
-            ArrayList<HolonObject> partiallySuppliedList = new ArrayList<HolonObject>();
-            /**
-             * HolonObjects that can get the spare energy
-             */
-            ArrayList<HolonObject> notSuppliedList = new ArrayList<HolonObject>();
-            /**
-             * supply Buildings with minimal Energy first, if conflicts happen
-             */
-            singleSubNet.getObjects().sort(new MinEnergyComparator(x));
-            for (HolonObject hl : singleSubNet.getObjects()) {
-            	hl.setCurrentSupply(0);
-                if (hl.getState() != HolonObject.NO_ENERGY
-                        && hl.getState() != HolonObject.PRODUCER) {
-                    for (int i = 0; i < hl.getConnections().size(); i++) {
-                        CpsEdge edge = hl.getConnectedTo().get(i);
-                        if (edge.isWorking() && edge.getFlow() > 0
-                                || edge.getCapacity() == CpsEdge.CAPACITY_INFINITE) {
-                            if ((production + consumption) >= 0) {
-                                if (energySurplus > 0) {
-                                    hl.setState(HolonObject.OVER_SUPPLIED);
-                                    hl.setCurrentSupply((-energySurplus/consumption+1)*hl.getCurrentEnergyAtTimeStep(x));
-                                } else {
-                                    hl.setState(HolonObject.SUPPLIED);
-                                    hl.setCurrentSupply(-hl.getCurrentEnergyAtTimeStep(x));
-                                }
-                            } else {
-                            	float minEnergy = hl.getMinEnergy(x);
-                                if ((production + minConsumption) >= 0) {
-                                    hl.setState(HolonObject.PARTIALLY_SUPPLIED);
-                                    currentProduction += minEnergy;
-                                    hl.setCurrentSupply(-minEnergy);
-                            		partiallySuppliedList.add(hl);
-                                } else if (hl.checkIfPartiallySupplied(timeStep)) {
-                                    hl.setState(HolonObject.PARTIALLY_SUPPLIED);
-                                    currentProduction += minEnergy;
-                                    hl.setCurrentSupply(-minEnergy);
-                            		partiallySuppliedList.add(hl);
-                                } else {
-                                	/**
-                                	 * Case that only some HolonObjects can be supplied
-                                	 */
-                                	if(-hl.getCurrentEnergyAtTimeStep(x)<=currentProduction){
-                                		hl.setState(HolonObject.PARTIALLY_SUPPLIED);
-                                		currentProduction += minEnergy;
-                                		hl.setCurrentSupply(-minEnergy);
-                                		partiallySuppliedList.add(hl);
-                                	}else if(-hl.getMinEnergy(x)<=currentProduction){
-                                		hl.setState(HolonObject.PARTIALLY_SUPPLIED);
-                                		currentProduction += minEnergy;
-                                		hl.setCurrentSupply(-minEnergy);
-                                		partiallySuppliedList.add(hl);
-                                	}else{
-                                		hl.setState(HolonObject.NOT_SUPPLIED);
-                                		hl.setCurrentSupply(0.0f);
-                                		notSuppliedList.add(hl);
-                                		//currentProduction += hl.getCurrentEnergyAtTimeStep(x);
-                                		
-                                	}
-                                }
-                            }
-                            hl.getCurrentEnergyAtTimeStep(x);
-                            break;
-                        }
-                    }
-                    
-                    
-                    /**
-                     * check if some object cn self supply itself
-                     */
-                    if (hl.checkIfPartiallySupplied(timeStep)
-                            && hl.getState() != HolonObject.SUPPLIED
-                            && hl.getState() != HolonObject.OVER_SUPPLIED) {
-                        hl.setState(HolonObject.PARTIALLY_SUPPLIED);
-                    }
-                }
-            }
-            
-            /**
-             * check if some partially supplied building might be fully supplied.
-             */
-            partiallySuppliedList.sort(new EnergyMinToMaxComparator(x));
-            for(HolonObject hl: partiallySuppliedList){
-            	float minEnergy = hl.getMinEnergy(x);
-            	currentProduction -= minEnergy;
-            	/*
-            	 * if possible, supply fully
-            	 */
-            	float currentEnergyAtTimeStep = hl.getCurrentEnergyAtTimeStep(x);
-				if(-currentEnergyAtTimeStep<=currentProduction){
-            		hl.setState(HolonObject.SUPPLIED);
-            		currentProduction += currentEnergyAtTimeStep;
-            		hl.setCurrentSupply(-currentEnergyAtTimeStep);
-            		 hl.getCurrentEnergyAtTimeStep(x);
-            	}else{
-            		currentProduction += minEnergy;
-            		notSuppliedList.add(hl);
-            	}
-            }
-            if(!notSuppliedList.isEmpty() && currentProduction>0){
-            	float energyPerHolon = currentProduction/notSuppliedList.size();
-            	for(HolonObject hl:notSuppliedList){
-            		hl.setCurrentSupply(hl.getCurrentSupply()+energyPerHolon);
-            		hl.getCurrentEnergyAtTimeStep(x);
-            	}
-            }
-        }
-        canvas.repaint();
-        flexPane.recalculate();
-    }
-
-    /**
-     * search for all flexible devices in the network and turn them on, until energy surplus = 0
-     * or all devices have been examined.
-     *
-     * This code could be compressed (cases inside over- and underproduction are the same), but we decided that it
-     * is better readable this way
-     *
-     * @param subNet        the subnet
-     * @param energySurplus the current surplus of energy
-     */
-    private void turnOnFlexibleDevices(SubNet subNet, float energySurplus, int timestep) {
-        for (HolonObject holonOb : subNet.getObjects()) {
-            for (HolonElement holonEl : holonOb.getElements()) {
-
-                // if this element is flexible and active (can be considered for calculations)
-                if (holonEl.isFlexible() && holonEl.isActive()) {
-                    float energyAvailableSingle = holonEl.getAvailableEnergyAt(timestep);
-                    float energyAvailableMultiple = energyAvailableSingle * holonEl.getAmount();
-
-                    // ------------- flexible consumer / OVERPRODUCTION -------------
-                    if (energyAvailableMultiple < 0 && energySurplus > 0) {
-
-                        // if there is more wasted energy than energy that this device can give, give all energy available
-                        if (Math.abs(energyAvailableMultiple) <= Math.abs(energySurplus)) {
-                            energySurplus += energyAvailableMultiple;
-                            // set the new energy consumption to the maximum
-                            holonEl.setEnergyPerElement(energyAvailableSingle);
-                            flexDevicesTurnedOnThisTurn.put(holonEl, energyAvailableMultiple);
-                        }
-                        // else: we just need to turn on part of the flexible energy available
-                        else {
-                            float energyNeeded = -energySurplus;
-                            energySurplus += energyNeeded;   // should give 0, but was kept this was for consistency
-                            // the energy needed divided through the amount of elements
-                            holonEl.setEnergyPerElement(energyNeeded / holonEl.getAmount());
-                            flexDevicesTurnedOnThisTurn.put(holonEl, energyNeeded);
-                        }
-                    }
-
-                    // ------------- flexible producer / UNDERPRODUCTION -------------
-                    else if (energyAvailableMultiple > 0 && energySurplus < 0) {
-
-                        // if there is more energy needed than this device can give, give all the energy available
-                        if (Math.abs(energyAvailableMultiple) <= Math.abs(energySurplus)) {
-                            energySurplus += energyAvailableMultiple;
-                            // set the new energy consumption to the maximum
-                            holonEl.setEnergyPerElement(energyAvailableSingle);
-                            flexDevicesTurnedOnThisTurn.put(holonEl, energyAvailableMultiple);
-                        }
-                        // else: we just need to turn on part of the flexible energy available
-                        else {
-                            float energyNeeded = -energySurplus;
-                            int i = 0;
-                            energySurplus += energyNeeded;   // should give 0, but was kept this was for consistency
-                            // the energy needed divided through the amount of elements
-                            holonEl.setEnergyPerElement(energyNeeded / holonEl.getAmount());
-                            flexDevicesTurnedOnThisTurn.put(holonEl, energyNeeded);
-                        }
-
-                    }
-                }
-
-                if (energySurplus == 0) {
-                    break;
-                }
-            }
-
-            if (energySurplus == 0) {
-                break;
-            }
-        }
-    }
-
-    /**
-     * Set Flow Simulation.
-     *
-     * @param sN Subnet
-     */
-    private void setFlowSimulation(SubNet sN) {
-        ArrayList<AbstractCpsObject> producers = new ArrayList<>();
-        AbstractCpsObject tmp = null;
-        tagTable = new HashMap<>();
-        // traverse all objects in this subnet
-        for (HolonObject hl : sN.getObjects()) {
-            float energy = hl.getCurrentEnergyAtTimeStep(timeStep);
-            // if their production is higher than their consumption
-            if (energy > 0) {
-                tagTable.put(hl.getId(), energy);
-                hl.addTag(hl.getId());
-                for (CpsEdge edge : hl.getConnections()) {
-                    if (edge.isWorking()) {
-                        // set other end of edge as tmp-object
-                        // and add this end to the other end's tag-list
-                        AbstractCpsObject a = edge.getA();
-                        AbstractCpsObject b = edge.getB();
-                        if (a.getId() == hl.getId()) {
-                            b.addTag(hl.getId());
-                            tmp = b;
-                        }
-                        if (b.getId() == hl.getId()) {
-                            a.addTag(hl.getId());
-                            tmp = a;
-                        }
-
-                        edge.setFlow(edge.getFlow() + energy);
-                        edge.calculateState();
-                        edge.addTag(hl.getId());
-                        if (edge.isWorking() && !producers.contains(tmp)) {
-                            if (tmp instanceof HolonSwitch) {
-                                if (((HolonSwitch) tmp).getState(timeStep)) {
-                                    producers.add(tmp);
-                                }
-                            } else if (!(tmp instanceof CpsUpperNode)) {
-                                producers.add(tmp);
-                            }
-                        }
-                    }
-                }
-            }
-        }
-        setFlowSimRec(producers, 0);
-    }
-
-    /**
-     * Set Flow Simulation Rec.
-     *
-     * @param nodes the nodes
-     * @param iter  the Iteration
-     */
-    private void setFlowSimRec(ArrayList<AbstractCpsObject> nodes, int iter) {
-        ArrayList<AbstractCpsObject> newNodes = new ArrayList<>();
-        ArrayList<CpsEdge> changedEdges = new ArrayList<>();
-        AbstractCpsObject tmp;
-        if (nodes.size() != 0) {
-            for (AbstractCpsObject cps : nodes) {
-                // check whether the cps is in a legit state if it is a switch
-                if (legitState(cps)) {
-                    for (CpsEdge edge : cps.getConnections()) {
-                        // is edge working
-                        // and does the edge's tag-list not (yet) contain all tags of the cps
-                        if (edge.isWorking()
-                                && (!(edge.containsTags(edge.getTags(), cps.getTag())))) {
-                            if (edge.getA().getId() == cps.getId()) {
-                                tmp = edge.getB();
-                            } else {
-                                tmp = edge.getA();
-                            }
-                            for (Integer tag : cps.getTag()) {
-                                if (!(edge.getTags().contains(tag))
-                                        && !(edge.getPseudoTags().contains(tag))) {
-                                    edge.setFlow(edge.getFlow() + tagTable.get(tag));
-                                    edge.addTag(tag);
-                                }
-                            }
-                            // uppernodes do not spread energy
-                            if (!(tmp instanceof CpsUpperNode)) {
-                                for (Integer tag : tmp.getTag()) {
-                                    if (!(edge.getTags().contains(tag))
-                                            && tagTable.get(tag) != null
-                                            && !(edge.getPseudoTags().contains(tag))) {
-                                        edge.setFlow(edge.getFlow() + tagTable.get(tag));
-                                        edge.addPseudoTag(tag);
-                                        changedEdges.add(edge);
-                                    }
-                                }
-                            }
-                            edge.calculateState();
-                            if (edge.isWorking()
-                                    && !(tmp instanceof CpsUpperNode)) {
-                                tmp.addAllPseudoTags(cps.getTag());
-                                if (!newNodes.contains(tmp)) {
-                                    newNodes.add(tmp);
-                                }
-                            }
-                        }
-                    }
-                }
-            }
-            setPseudoTags(newNodes, changedEdges);
-            setFlowSimRec(newNodes, iter + 1);
-        }
-    }
-
-    /**
-     * Set the Pseudo Tags.
-     *
-     * @param nodes Array of AbstractCpsObjects
-     */
-    private void setPseudoTags(ArrayList<AbstractCpsObject> nodes, ArrayList<CpsEdge> edges) {
-        for (AbstractCpsObject node : nodes) {
-            node.recalculateTags();
-            node.setPseudoTags(new ArrayList<>());
-        }
-        for (CpsEdge edge : edges) {
-            edge.recalculateTags();
-            edge.setPseudoTag(new ArrayList<>());
-        }
-    }
-
-    /**
-     * Reset the Connection.
-     *
-     * @param cps          CpsObject
-     * @param visitedObj   the visited Objects
-     * @param visitedEdges the visited Edges
-     */
-    private void resetConnections(AbstractCpsObject cps, ArrayList<Integer> visitedObj,
-                                  ArrayList<CpsEdge> visitedEdges) {
-        visitedObj.add(cps.getId());
-        cps.resetTags();
-        for (CpsEdge e : cps.getConnections()) {
-            if (!(visitedEdges.contains(e))) {
-                e.setFlow(0);
-                e.calculateState();
-                e.setTags(new ArrayList<>());
-                visitedEdges.add(e);
-                if (!(visitedObj.contains(e.getA().getId()))) {
-                    resetConnections(e.getA(), visitedObj, visitedEdges);
-                    e.getA().resetTags();
-                }
-                if (!(visitedObj.contains(e.getB().getId()))) {
-                    resetConnections(e.getB(), visitedObj, visitedEdges);
-                    e.getB().resetTags();
-                }
-            }
-        }
-    }
-
-    /**
-     * calculates the energy of either all producers or consumers.
-     * Flexible devices are filtered out
-     *
-     * @param type Type
-     * @param sN   Subnet
-     * @param x    Integer
-     * @return The Energy
-     */
-    private float calculateEnergyWithoutFlexDevices(String type, SubNet sN, int x) {
-        float energy = 0;
-        for (HolonObject hl : sN.getObjects()) {
-            float currentEnergyWithoutFlexibles = hl.getCurrentEnergyAtTimeStepWithoutFlexiblesAndResetFlexibles(x);
-
-            if (type.equals("prod")) {
-                if (currentEnergyWithoutFlexibles > 0) {
-                    energy += currentEnergyWithoutFlexibles;
-                    hl.setState(HolonObject.PRODUCER);
-                }
-            }
-            if (type.equals("cons")) {
-                if (currentEnergyWithoutFlexibles < 0) {
-                    energy = energy + currentEnergyWithoutFlexibles;
-                    hl.setState(HolonObject.NOT_SUPPLIED);
-                }
-            }
-            if (currentEnergyWithoutFlexibles == 0) {
-                hl.setState(HolonObject.NO_ENERGY);
-            }
-        }
-        return energy;
-    }
-
-    /**
-     * calculates the energy of either all producers or consumers.
-     * Flexible devices are filtered out
-     *
-     * @param type Type
-     * @param sN   Subnet
-     * @param x    Integer
-     * @return The Energy
-     */
-    private float calculateEnergyWithFlexDevices(String type, SubNet sN, int x) {
-        float energy = 0;
-        for (HolonObject hl : sN.getObjects()) {
-            float currentEnergy = hl.getCurrentEnergyAtTimeStep(x);
-
-            if (type.equals("prod")) {
-                if (currentEnergy > 0) {
-                    energy += currentEnergy;
-                    hl.setState(HolonObject.PRODUCER);
-                }
-            }
-            if (type.equals("cons")) {
-                if (currentEnergy < 0) {
-                    energy = energy + currentEnergy;
-                    hl.setState(HolonObject.NOT_SUPPLIED);
-                }
-            }
-            if (currentEnergy == 0) {
-                hl.setState(HolonObject.NO_ENERGY);
-            }
-        }
-        return energy;
-    }
-
-    /**
-     * Calculate the Minimum Energy.
-     *
-     * @param sN Subnet
-     * @param x  Integer
-     * @return the Calculated minimum Energy
-     */
-    private float calculateMinimumEnergy(SubNet sN, int x) {
-        float min = 0;
-        float minElement = 0;
-        for (HolonObject hl : sN.getObjects()) {
-            if (hl.getElements().size() > 0 && hl.getElements().get(0).getOverallEnergyAtTimeStep(x) < 0) {
-                minElement = hl.getElements().get(0).getOverallEnergyAtTimeStep(x);
-            }
-            for (HolonElement he : hl.getElements()) {
-                float overallEnergy = he.getOverallEnergyAtTimeStep(x);
-                if (minElement < overallEnergy && overallEnergy < 0) {
-                    minElement = overallEnergy;
-                }
-            }
-            min = min + minElement;
-        }
-        return min;
-    }
-
-    /**
-     * generates all subNets from all objectsToHandle.
-     */
-    private void searchForSubNets() {
-        subNets = new ArrayList<>();
-        brokenEdges.clear();
-        boolean end = false;
-        int i = 0;
-        AbstractCpsObject cps;
-        if (objectsToHandle.size() > 0) {
-            while (!end) {
-                cps = objectsToHandle.get(i);
-                SubNet singleSubNet = new SubNet(new ArrayList<>(), new ArrayList<>(),
-                        new ArrayList<>());
-                singleSubNet = buildSubNet(cps, new ArrayList<>(), singleSubNet);
-                if (singleSubNet.getObjects().size() != 0) {
-                    subNets.add(singleSubNet);
-                }
-                if (0 == objectsToHandle.size()) {
-                    end = true;
-                }
-            }
-        }
-    }
-
-    /**
-     * recursivly generates a subnet of all objects, that one specific object is
-     * connected to.
-     *
-     * @param cps     AbstractCpsObject
-     * @param visited visited Array of Integer
-     * @param sN      Subnets
-     * @return Subnet
-     */
-    private SubNet buildSubNet(AbstractCpsObject cps, ArrayList<Integer> visited, SubNet sN) {
-        visited.add(cps.getId());
-        if (cps instanceof HolonObject) {
-            sN.getObjects().add((HolonObject) cps);
-        }
-        if (cps instanceof HolonSwitch) {
-            sN.getSwitches().add((HolonSwitch) cps);
-        }
-        removeFromToHandle(cps.getId());
-        AbstractCpsObject a;
-        AbstractCpsObject b;
-        for (CpsEdge edge : cps.getConnections()) {
-            if (edge.isWorking()) {
-                a = edge.getA();
-                b = edge.getB();
-                if (!(cps instanceof HolonSwitch)) {
-                    if (!(sN.getEdges().contains(edge))) {
-                        sN.getEdges().add(edge);
-                    }
-                }
-                if (cps instanceof HolonSwitch && ((HolonSwitch) cps).getState(timeStep)) {
-                    if (!(sN.getEdges().contains(edge))) {
-                        sN.getEdges().add(edge);
-                    }
-                }
-                if (!visited.contains(a.getId()) && legitState(cps) && !(a instanceof CpsUpperNode)) {
-                    sN = buildSubNet(a, visited, sN);
-                }
-                if (!visited.contains(b.getId()) && legitState(cps) && !(b instanceof CpsUpperNode)) {
-                    sN = buildSubNet(b, visited, sN);
-                }
-                if (a instanceof CpsUpperNode && a.getId() != cps.getId()) {
-                    edge.setConnected(CpsEdge.CON_UPPER_NODE_NOT_INSIDE);
-                    checkForConnectedStates(b, (CpsUpperNode) a, edge);
-                }
-                if (b instanceof CpsUpperNode && b.getId() != cps.getId()) {
-                    edge.setConnected(CpsEdge.CON_UPPER_NODE_NOT_INSIDE);
-                    checkForConnectedStates(a, (CpsUpperNode) b, edge);
-                }
-            } else {
-                brokenEdges.add(edge);
-            }
-        }
-        return sN;
-    }
-
-    /**
-     * is the Switch in a legitimate State.
-     *
-     * @param current AbstractCpsObject
-     * @return boolean
-     */
-    private boolean legitState(AbstractCpsObject current) {
-        return !(current instanceof HolonSwitch)
-                || ((HolonSwitch) current).getState(timeStep);
-    }
-
-//    /**
-//     * ensures that objectsToHandle only contains HolonObjects.
-//     */
-//	public void cleanObjectsToHandle() {
-//		for (int i = 0; i < objectsToHandle.size(); i++) {
-//			if (!(objectsToHandle.get(i) instanceof HolonObject)) {
-//				objectsToHandle.remove(i);
-//			}
-//		}
-//	}
-
-    /**
-     * removes an Object that already has been handled.
-     *
-     * @param id the Object ID
-     */
-    private void removeFromToHandle(int id) {
-        for (int i = 0; i < objectsToHandle.size(); i++) {
-            if (objectsToHandle.get(i).getId() == id) {
-                objectsToHandle.remove(i);
-            }
-        }
-    }
-
-    /**
-     * copies the data of an array of Objects.
-     *
-     * @param toCopy the ArrayList of CpsObjects co Copy
-     */
-    private void copyObjects(ArrayList<AbstractCpsObject> toCopy) {
-        for (AbstractCpsObject cps : toCopy) {
-            if (cps instanceof CpsUpperNode) {
-                copyObjects(((CpsUpperNode) cps).getNodes());
-            } else {
-                objectsToHandle.add(cps);
-            }
-        }
-    }
-
-    /**
-     * Prints the Components auf all subnets.
-     */
-    private void printNetsToConsole() {
-        for (int i = 0; i < subNets.size(); i++) {
-            SubNet subNet = subNets.get(i);
-            System.out.println("SUBNET NR:" + i);
-            subNet.toString(timeStep);
-        }
-    }
-
-    /**
-     * Set the Canvas.
-     *
-     * @param can the Canvas
-     */
-    public void setCanvas(MyCanvas can) {
-        canvas = can;
-    }
-
-    /**
-     * Reset all Data to the current state of the Model.
-     */
-    public void reset() {
-        objectsToHandle = new ArrayList<>();
-        copyObjects(model.getObjectsOnCanvas());
-        flexDevicesTurnedOnThisTurn = new HashMap<>();
-    }
-
-    /**
-     * Resets the State of all Edges
-     */
-    private void resetEdges() {
-        for (CpsEdge e : brokenEdges) {
-            e.setWorkingState(true);
-        }
-    }
-
-    /**
-     * Resets the State for the whole Simulation Model
-     */
-    void resetSimulation() {
-        reset();
-        resetEdges();
-    }
-
-    /**
-     * Get all Subnets.
-     *
-     * @return all Subnets
-     */
-    public ArrayList<SubNet> getSubNets() {
-        return subNets;
-    }
-
-    /**
-     * Get broken Edges
-     */
-//    public ArrayList<CpsEdge> getBrokenEdges() {
-//        return brokenEdges;
-//    }
-
-    /**
-     * checks whether a given object is connected to an object inside the upperNode.
-     * if yes, the state for the edge is changed in "connected" or "not connected"
-     */
-    private void checkForConnectedStates(AbstractCpsObject cps, CpsUpperNode cUNode, CpsEdge theEdge) {
-        AbstractCpsObject tmp;
-        for (CpsEdge edge : cps.getConnections()) {
-            if (edge.getA().getId() == cps.getId()) {
-                tmp = edge.getB();
-            } else {
-                tmp = edge.getA();
-            }
-            if (cUNode.getNodes().contains(tmp)) {
-                if (tmp instanceof CpsUpperNode) {
-                    checkForConnectedStates(cps, (CpsUpperNode) tmp, theEdge);
-                } else {
-                    theEdge.setConnected(CpsEdge.CON_UPPER_NODE_AND_INSIDE);
-                    break;
-                }
-            }
-        }
-    }
-
-    public FlexiblePane getFlexiblePane() {
-        return flexPane;
-    }
-
-    void setFlexiblePane(FlexiblePane fp) {
-        flexPane = fp;
-    }
+	int global = 0;
+	private Model model;
+	private ArrayList<AbstractCpsObject> objectsToHandle;
+	// private ArrayList<CpsEdge> allConnections;
+	private ArrayList<SubNet> subNets;
+	private ArrayList<CpsEdge> brokenEdges;
+	private MyCanvas canvas;
+	private int timeStep;
+	private HashMap<Integer, Float> tagTable = new HashMap<>();
+	private FlexiblePane flexPane;
+
+	private HashMap<HolonElement, Float> flexDevicesTurnedOnThisTurn = new HashMap<>();
+
+	/**
+	 * One Element of each HolonObject will be powered first, starting with the
+	 * smallest Demand. If alle HolonObjects have an active Element, the
+	 * simulation will try to fully suplly as many HolonObjects as possible.
+	 */
+	public static final short fairnessMininumDemandFirst = 0;
+
+	/**
+	 * All HolonObjects will receive the same amount of energy.
+	 */
+	public static final short fairnessAllEqual = 1;
+
+	/**
+	 * Constructor.
+	 *
+	 * @param m
+	 *            Model
+	 */
+	SimulationManager(Model m) {
+		canvas = null;
+		model = m;
+		subNets = new ArrayList<>();
+		brokenEdges = new ArrayList<>();
+	}
+
+	/**
+	 * calculates the flow of the edges and the supply for objects.
+	 *
+	 * @param x
+	 *            current Iteration
+	 */
+	void calculateStateForTimeStep(int x) {
+		reset();
+		timeStep = x;
+		searchForSubNets();
+		for (SubNet singleSubNet : subNets) {
+			resetConnections(singleSubNet.getObjects().get(0),
+					new ArrayList<>(), new ArrayList<>());
+		}
+		for (SubNet singleSubNet : subNets) {
+			float production = calculateEnergyWithoutFlexDevices("prod",
+					singleSubNet, timeStep);
+			float consumption = calculateEnergyWithoutFlexDevices("cons",
+					singleSubNet, timeStep);
+			// surplus of energy is computed by sum, since consumption is a
+			// negative value
+			float energySurplus = production + consumption;
+
+			float minConsumption = calculateMinimumEnergy(singleSubNet,
+					timeStep);
+
+			// --------------- use flexible devices ---------------
+			if (energySurplus != 0 && model.useFlexibleDevices()) {
+				turnOnFlexibleDevices(singleSubNet, energySurplus, x);
+
+				// if (!flexDevicesTurnedOnThisTurn.isEmpty()) {
+				// System.out.println("The following devices were turned on in this turn: ");
+				// System.out.println(flexDevicesTurnedOnThisTurn.toString());
+				// }
+
+				// recompute after having examined/turned on all flexible
+				// devices
+				production = calculateEnergyWithFlexDevices("prod",
+						singleSubNet, timeStep);
+				consumption = calculateEnergyWithFlexDevices("cons",
+						singleSubNet, timeStep);
+				energySurplus = production + consumption;
+			}
+
+			// --------------- set flow simulation ---------------
+			setFlowSimulation(singleSubNet);
+
+			// --------------- visualise graph ---------------
+
+			/**
+			 * production of subnets, that might be partially turned on/off
+			 */
+			float currentProduction = production;
+			/**
+			 * HolonObjects that can be partially Supplied but might be fully
+			 * Supplied
+			 */
+			ArrayList<HolonObject> partiallySuppliedList = new ArrayList<HolonObject>();
+			/**
+			 * HolonObjects that can get the spare energy
+			 */
+			ArrayList<HolonObject> notSuppliedList = new ArrayList<HolonObject>();
+			/**
+			 * number of HolonObjects that need to be supplied
+			 */
+			long numberOfConsumers;
+			/**
+			 * energy each HolonObject receives in AlleEqualModus
+			 */
+			float energyPerHolonObject = 0;
+			if (model.getFairnessModel() == fairnessMininumDemandFirst) {
+				/**
+				 * supply Buildings with minimal Energy first, if conflicts
+				 * happen
+				 */
+				singleSubNet.getObjects().sort(new MinEnergyComparator(x));
+			} else if (model.getFairnessModel() == fairnessAllEqual) {
+				/*
+				 * give every building (just consumer) the same energy
+				 */
+				numberOfConsumers = singleSubNet
+						.getObjects()
+						.stream()
+						.filter(hl -> (hl.getState() != HolonObject.NO_ENERGY
+								&& hl.getState() != HolonObject.PRODUCER && hl
+								.getConnectedTo().stream()
+								.filter(e -> (e.getFlow() > 0)).count() > 0))
+						.count();
+				if (numberOfConsumers != 0)
+					energyPerHolonObject = production / numberOfConsumers;
+			}
+			for (HolonObject hl : singleSubNet.getObjects()) {
+				hl.setCurrentSupply(0);
+				if (hl.getState() != HolonObject.NO_ENERGY
+						&& hl.getState() != HolonObject.PRODUCER) {
+					for (int i = 0; i < hl.getConnections().size(); i++) {
+						CpsEdge edge = hl.getConnectedTo().get(i);
+						if (edge.isWorking()
+								&& edge.getFlow() > 0
+								|| edge.getCapacity() == CpsEdge.CAPACITY_INFINITE) {
+
+							if (model.getFairnessModel() == fairnessAllEqual) {
+								/* fairness: everyone receives the Same Energy */
+								float neededEnergy = hl
+										.getCurrentEnergyAtTimeStep(x);
+								if (neededEnergy > 0) {
+									hl.setState(HolonObject.PRODUCER);
+								} else if (energyPerHolonObject > -neededEnergy) {
+									hl.setState(HolonObject.OVER_SUPPLIED);
+								} else if (energyPerHolonObject == -neededEnergy) {
+									hl.setState(HolonObject.SUPPLIED);
+								} else if (energyPerHolonObject >= -hl
+										.getMinEnergy(x)) {
+									hl.setState(HolonObject.PARTIALLY_SUPPLIED);
+								} else {
+									hl.setState(HolonObject.NOT_SUPPLIED);
+								}
+								hl.setCurrentSupply(energyPerHolonObject);
+							} else if (model.getFairnessModel() == fairnessMininumDemandFirst) {
+								/* fairness: minimum demand gets Energy first */
+								if ((production + consumption) >= 0) {
+									if (energySurplus > 0) {
+										hl.setState(HolonObject.OVER_SUPPLIED);
+										hl.setCurrentSupply((-energySurplus
+												/ consumption + 1)
+												* hl.getCurrentEnergyAtTimeStep(x));
+									} else {
+										hl.setState(HolonObject.SUPPLIED);
+										hl.setCurrentSupply(-hl
+												.getCurrentEnergyAtTimeStep(x));
+									}
+								} else {
+									float minEnergy = hl.getMinEnergy(x);
+									if ((production + minConsumption) >= 0) {
+										hl.setState(HolonObject.PARTIALLY_SUPPLIED);
+										currentProduction += minEnergy;
+										hl.setCurrentSupply(-minEnergy);
+										partiallySuppliedList.add(hl);
+									} else if (hl
+											.checkIfPartiallySupplied(timeStep)) {
+										hl.setState(HolonObject.PARTIALLY_SUPPLIED);
+										currentProduction += minEnergy;
+										hl.setCurrentSupply(-minEnergy);
+										partiallySuppliedList.add(hl);
+									} else {
+										/**
+										 * Case that only some HolonObjects can
+										 * be supplied
+										 */
+										if (-hl.getCurrentEnergyAtTimeStep(x) <= currentProduction) {
+											hl.setState(HolonObject.PARTIALLY_SUPPLIED);
+											currentProduction += minEnergy;
+											hl.setCurrentSupply(-minEnergy);
+											partiallySuppliedList.add(hl);
+										} else if (-hl.getMinEnergy(x) <= currentProduction) {
+											hl.setState(HolonObject.PARTIALLY_SUPPLIED);
+											currentProduction += minEnergy;
+											hl.setCurrentSupply(-minEnergy);
+											partiallySuppliedList.add(hl);
+										} else {
+											hl.setState(HolonObject.NOT_SUPPLIED);
+											hl.setCurrentSupply(0.0f);
+											notSuppliedList.add(hl);
+											// currentProduction +=
+											// hl.getCurrentEnergyAtTimeStep(x);
+
+										}
+									}
+								}
+							}
+							hl.getCurrentEnergyAtTimeStep(x);
+							break;
+						}
+					}
+
+					/**
+					 * check if some object cn self supply itself
+					 */
+					if (hl.checkIfPartiallySupplied(timeStep)
+							&& hl.getState() != HolonObject.SUPPLIED
+							&& hl.getState() != HolonObject.OVER_SUPPLIED) {
+						hl.setState(HolonObject.PARTIALLY_SUPPLIED);
+					}
+				}
+			}
+
+			if (model.getFairnessModel() == fairnessMininumDemandFirst) {
+				/**
+				 * check if some partially supplied building might be fully
+				 * supplied.
+				 */
+				partiallySuppliedList.sort(new EnergyMinToMaxComparator(x));
+				for (HolonObject hl : partiallySuppliedList) {
+					float minEnergy = hl.getMinEnergy(x);
+					currentProduction -= minEnergy;
+					/*
+					 * if possible, supply fully
+					 */
+					float currentEnergyAtTimeStep = hl
+							.getCurrentEnergyAtTimeStep(x);
+					if (-currentEnergyAtTimeStep <= currentProduction) {
+						hl.setState(HolonObject.SUPPLIED);
+						currentProduction += currentEnergyAtTimeStep;
+						hl.setCurrentSupply(-currentEnergyAtTimeStep);
+						hl.getCurrentEnergyAtTimeStep(x);
+					} else {
+						currentProduction += minEnergy;
+						notSuppliedList.add(hl);
+					}
+				}
+				if (!notSuppliedList.isEmpty() && currentProduction > 0) {
+					float energyPerHolon = currentProduction
+							/ notSuppliedList.size();
+					for (HolonObject hl : notSuppliedList) {
+						hl.setCurrentSupply(hl.getCurrentSupply()
+								+ energyPerHolon);
+						hl.getCurrentEnergyAtTimeStep(x);
+					}
+				}
+			}
+		}
+		canvas.repaint();
+		flexPane.recalculate();
+	}
+
+	/**
+	 * search for all flexible devices in the network and turn them on, until
+	 * energy surplus = 0 or all devices have been examined.
+	 *
+	 * This code could be compressed (cases inside over- and underproduction are
+	 * the same), but we decided that it is better readable this way
+	 *
+	 * @param subNet
+	 *            the subnet
+	 * @param energySurplus
+	 *            the current surplus of energy
+	 */
+	private void turnOnFlexibleDevices(SubNet subNet, float energySurplus,
+			int timestep) {
+		for (HolonObject holonOb : subNet.getObjects()) {
+			for (HolonElement holonEl : holonOb.getElements()) {
+
+				// if this element is flexible and active (can be considered for
+				// calculations)
+				if (holonEl.isFlexible() && holonEl.isActive()) {
+					float energyAvailableSingle = holonEl
+							.getAvailableEnergyAt(timestep);
+					float energyAvailableMultiple = energyAvailableSingle
+							* holonEl.getAmount();
+
+					// ------------- flexible consumer / OVERPRODUCTION
+					// -------------
+					if (energyAvailableMultiple < 0 && energySurplus > 0) {
+
+						// if there is more wasted energy than energy that this
+						// device can give, give all energy available
+						if (Math.abs(energyAvailableMultiple) <= Math
+								.abs(energySurplus)) {
+							energySurplus += energyAvailableMultiple;
+							// set the new energy consumption to the maximum
+							holonEl.setEnergyPerElement(energyAvailableSingle);
+							flexDevicesTurnedOnThisTurn.put(holonEl,
+									energyAvailableMultiple);
+						}
+						// else: we just need to turn on part of the flexible
+						// energy available
+						else {
+							float energyNeeded = -energySurplus;
+							energySurplus += energyNeeded; // should give 0, but
+															// was kept this was
+															// for consistency
+							// the energy needed divided through the amount of
+							// elements
+							holonEl.setEnergyPerElement(energyNeeded
+									/ holonEl.getAmount());
+							flexDevicesTurnedOnThisTurn.put(holonEl,
+									energyNeeded);
+						}
+					}
+
+					// ------------- flexible producer / UNDERPRODUCTION
+					// -------------
+					else if (energyAvailableMultiple > 0 && energySurplus < 0) {
+
+						// if there is more energy needed than this device can
+						// give, give all the energy available
+						if (Math.abs(energyAvailableMultiple) <= Math
+								.abs(energySurplus)) {
+							energySurplus += energyAvailableMultiple;
+							// set the new energy consumption to the maximum
+							holonEl.setEnergyPerElement(energyAvailableSingle);
+							flexDevicesTurnedOnThisTurn.put(holonEl,
+									energyAvailableMultiple);
+						}
+						// else: we just need to turn on part of the flexible
+						// energy available
+						else {
+							float energyNeeded = -energySurplus;
+							int i = 0;
+							energySurplus += energyNeeded; // should give 0, but
+															// was kept this was
+															// for consistency
+							// the energy needed divided through the amount of
+							// elements
+							holonEl.setEnergyPerElement(energyNeeded
+									/ holonEl.getAmount());
+							flexDevicesTurnedOnThisTurn.put(holonEl,
+									energyNeeded);
+						}
+
+					}
+				}
+
+				if (energySurplus == 0) {
+					break;
+				}
+			}
+
+			if (energySurplus == 0) {
+				break;
+			}
+		}
+	}
+
+	/**
+	 * Set Flow Simulation.
+	 *
+	 * @param sN
+	 *            Subnet
+	 */
+	private void setFlowSimulation(SubNet sN) {
+		ArrayList<AbstractCpsObject> producers = new ArrayList<>();
+		AbstractCpsObject tmp = null;
+		tagTable = new HashMap<>();
+		// traverse all objects in this subnet
+		for (HolonObject hl : sN.getObjects()) {
+			float energy = hl.getCurrentEnergyAtTimeStep(timeStep);
+			// if their production is higher than their consumption
+			if (energy > 0) {
+				tagTable.put(hl.getId(), energy);
+				hl.addTag(hl.getId());
+				for (CpsEdge edge : hl.getConnections()) {
+					if (edge.isWorking()) {
+						// set other end of edge as tmp-object
+						// and add this end to the other end's tag-list
+						AbstractCpsObject a = edge.getA();
+						AbstractCpsObject b = edge.getB();
+						if (a.getId() == hl.getId()) {
+							b.addTag(hl.getId());
+							tmp = b;
+						}
+						if (b.getId() == hl.getId()) {
+							a.addTag(hl.getId());
+							tmp = a;
+						}
+
+						edge.setFlow(edge.getFlow() + energy);
+						edge.calculateState();
+						edge.addTag(hl.getId());
+						if (edge.isWorking() && !producers.contains(tmp)) {
+							if (tmp instanceof HolonSwitch) {
+								if (((HolonSwitch) tmp).getState(timeStep)) {
+									producers.add(tmp);
+								}
+							} else if (!(tmp instanceof CpsUpperNode)) {
+								producers.add(tmp);
+							}
+						}
+					}
+				}
+			}
+		}
+		setFlowSimRec(producers, 0);
+	}
+
+	/**
+	 * Set Flow Simulation Rec.
+	 *
+	 * @param nodes
+	 *            the nodes
+	 * @param iter
+	 *            the Iteration
+	 */
+	private void setFlowSimRec(ArrayList<AbstractCpsObject> nodes, int iter) {
+		ArrayList<AbstractCpsObject> newNodes = new ArrayList<>();
+		ArrayList<CpsEdge> changedEdges = new ArrayList<>();
+		AbstractCpsObject tmp;
+		if (nodes.size() != 0) {
+			for (AbstractCpsObject cps : nodes) {
+				// check whether the cps is in a legit state if it is a switch
+				if (legitState(cps)) {
+					for (CpsEdge edge : cps.getConnections()) {
+						// is edge working
+						// and does the edge's tag-list not (yet) contain all
+						// tags of the cps
+						if (edge.isWorking()
+								&& (!(edge.containsTags(edge.getTags(),
+										cps.getTag())))) {
+							if (edge.getA().getId() == cps.getId()) {
+								tmp = edge.getB();
+							} else {
+								tmp = edge.getA();
+							}
+							for (Integer tag : cps.getTag()) {
+								if (!(edge.getTags().contains(tag))
+										&& !(edge.getPseudoTags().contains(tag))) {
+									edge.setFlow(edge.getFlow()
+											+ tagTable.get(tag));
+									edge.addTag(tag);
+								}
+							}
+							// uppernodes do not spread energy
+							if (!(tmp instanceof CpsUpperNode)) {
+								for (Integer tag : tmp.getTag()) {
+									if (!(edge.getTags().contains(tag))
+											&& tagTable.get(tag) != null
+											&& !(edge.getPseudoTags()
+													.contains(tag))) {
+										edge.setFlow(edge.getFlow()
+												+ tagTable.get(tag));
+										edge.addPseudoTag(tag);
+										changedEdges.add(edge);
+									}
+								}
+							}
+							edge.calculateState();
+							if (edge.isWorking()
+									&& !(tmp instanceof CpsUpperNode)) {
+								tmp.addAllPseudoTags(cps.getTag());
+								if (!newNodes.contains(tmp)) {
+									newNodes.add(tmp);
+								}
+							}
+						}
+					}
+				}
+			}
+			setPseudoTags(newNodes, changedEdges);
+			setFlowSimRec(newNodes, iter + 1);
+		}
+	}
+
+	/**
+	 * Set the Pseudo Tags.
+	 *
+	 * @param nodes
+	 *            Array of AbstractCpsObjects
+	 */
+	private void setPseudoTags(ArrayList<AbstractCpsObject> nodes,
+			ArrayList<CpsEdge> edges) {
+		for (AbstractCpsObject node : nodes) {
+			node.recalculateTags();
+			node.setPseudoTags(new ArrayList<>());
+		}
+		for (CpsEdge edge : edges) {
+			edge.recalculateTags();
+			edge.setPseudoTag(new ArrayList<>());
+		}
+	}
+
+	/**
+	 * Reset the Connection.
+	 *
+	 * @param cps
+	 *            CpsObject
+	 * @param visitedObj
+	 *            the visited Objects
+	 * @param visitedEdges
+	 *            the visited Edges
+	 */
+	private void resetConnections(AbstractCpsObject cps,
+			ArrayList<Integer> visitedObj, ArrayList<CpsEdge> visitedEdges) {
+		visitedObj.add(cps.getId());
+		cps.resetTags();
+		for (CpsEdge e : cps.getConnections()) {
+			if (!(visitedEdges.contains(e))) {
+				e.setFlow(0);
+				e.calculateState();
+				e.setTags(new ArrayList<>());
+				visitedEdges.add(e);
+				if (!(visitedObj.contains(e.getA().getId()))) {
+					resetConnections(e.getA(), visitedObj, visitedEdges);
+					e.getA().resetTags();
+				}
+				if (!(visitedObj.contains(e.getB().getId()))) {
+					resetConnections(e.getB(), visitedObj, visitedEdges);
+					e.getB().resetTags();
+				}
+			}
+		}
+	}
+
+	/**
+	 * calculates the energy of either all producers or consumers. Flexible
+	 * devices are filtered out
+	 *
+	 * @param type
+	 *            Type
+	 * @param sN
+	 *            Subnet
+	 * @param x
+	 *            Integer
+	 * @return The Energy
+	 */
+	private float calculateEnergyWithoutFlexDevices(String type, SubNet sN,
+			int x) {
+		float energy = 0;
+		for (HolonObject hl : sN.getObjects()) {
+			float currentEnergyWithoutFlexibles = hl
+					.getCurrentEnergyAtTimeStepWithoutFlexiblesAndResetFlexibles(x);
+
+			if (type.equals("prod")) {
+				if (currentEnergyWithoutFlexibles > 0) {
+					energy += currentEnergyWithoutFlexibles;
+					hl.setState(HolonObject.PRODUCER);
+				}
+			}
+			if (type.equals("cons")) {
+				if (currentEnergyWithoutFlexibles < 0) {
+					energy = energy + currentEnergyWithoutFlexibles;
+					hl.setState(HolonObject.NOT_SUPPLIED);
+				}
+			}
+			if (currentEnergyWithoutFlexibles == 0) {
+				hl.setState(HolonObject.NO_ENERGY);
+			}
+		}
+		return energy;
+	}
+
+	/**
+	 * calculates the energy of either all producers or consumers. Flexible
+	 * devices are filtered out
+	 *
+	 * @param type
+	 *            Type
+	 * @param sN
+	 *            Subnet
+	 * @param x
+	 *            Integer
+	 * @return The Energy
+	 */
+	private float calculateEnergyWithFlexDevices(String type, SubNet sN, int x) {
+		float energy = 0;
+		for (HolonObject hl : sN.getObjects()) {
+			float currentEnergy = hl.getCurrentEnergyAtTimeStep(x);
+
+			if (type.equals("prod")) {
+				if (currentEnergy > 0) {
+					energy += currentEnergy;
+					hl.setState(HolonObject.PRODUCER);
+				}
+			}
+			if (type.equals("cons")) {
+				if (currentEnergy < 0) {
+					energy = energy + currentEnergy;
+					hl.setState(HolonObject.NOT_SUPPLIED);
+				}
+			}
+			if (currentEnergy == 0) {
+				hl.setState(HolonObject.NO_ENERGY);
+			}
+		}
+		return energy;
+	}
+
+	/**
+	 * Calculate the Minimum Energy.
+	 *
+	 * @param sN
+	 *            Subnet
+	 * @param x
+	 *            Integer
+	 * @return the Calculated minimum Energy
+	 */
+	private float calculateMinimumEnergy(SubNet sN, int x) {
+		float min = 0;
+		float minElement = 0;
+		for (HolonObject hl : sN.getObjects()) {
+			if (hl.getElements().size() > 0
+					&& hl.getElements().get(0).getOverallEnergyAtTimeStep(x) < 0) {
+				minElement = hl.getElements().get(0)
+						.getOverallEnergyAtTimeStep(x);
+			}
+			for (HolonElement he : hl.getElements()) {
+				float overallEnergy = he.getOverallEnergyAtTimeStep(x);
+				if (minElement < overallEnergy && overallEnergy < 0) {
+					minElement = overallEnergy;
+				}
+			}
+			min = min + minElement;
+		}
+		return min;
+	}
+
+	/**
+	 * generates all subNets from all objectsToHandle.
+	 */
+	private void searchForSubNets() {
+		subNets = new ArrayList<>();
+		brokenEdges.clear();
+		boolean end = false;
+		int i = 0;
+		AbstractCpsObject cps;
+		if (objectsToHandle.size() > 0) {
+			while (!end) {
+				cps = objectsToHandle.get(i);
+				SubNet singleSubNet = new SubNet(new ArrayList<>(),
+						new ArrayList<>(), new ArrayList<>());
+				singleSubNet = buildSubNet(cps, new ArrayList<>(), singleSubNet);
+				if (singleSubNet.getObjects().size() != 0) {
+					subNets.add(singleSubNet);
+				}
+				if (0 == objectsToHandle.size()) {
+					end = true;
+				}
+			}
+		}
+	}
+
+	/**
+	 * recursivly generates a subnet of all objects, that one specific object is
+	 * connected to.
+	 *
+	 * @param cps
+	 *            AbstractCpsObject
+	 * @param visited
+	 *            visited Array of Integer
+	 * @param sN
+	 *            Subnets
+	 * @return Subnet
+	 */
+	private SubNet buildSubNet(AbstractCpsObject cps,
+			ArrayList<Integer> visited, SubNet sN) {
+		visited.add(cps.getId());
+		if (cps instanceof HolonObject) {
+			sN.getObjects().add((HolonObject) cps);
+		}
+		if (cps instanceof HolonSwitch) {
+			sN.getSwitches().add((HolonSwitch) cps);
+		}
+		removeFromToHandle(cps.getId());
+		AbstractCpsObject a;
+		AbstractCpsObject b;
+		for (CpsEdge edge : cps.getConnections()) {
+			if (edge.isWorking()) {
+				a = edge.getA();
+				b = edge.getB();
+				if (!(cps instanceof HolonSwitch)) {
+					if (!(sN.getEdges().contains(edge))) {
+						sN.getEdges().add(edge);
+					}
+				}
+				if (cps instanceof HolonSwitch
+						&& ((HolonSwitch) cps).getState(timeStep)) {
+					if (!(sN.getEdges().contains(edge))) {
+						sN.getEdges().add(edge);
+					}
+				}
+				if (!visited.contains(a.getId()) && legitState(cps)
+						&& !(a instanceof CpsUpperNode)) {
+					sN = buildSubNet(a, visited, sN);
+				}
+				if (!visited.contains(b.getId()) && legitState(cps)
+						&& !(b instanceof CpsUpperNode)) {
+					sN = buildSubNet(b, visited, sN);
+				}
+				if (a instanceof CpsUpperNode && a.getId() != cps.getId()) {
+					edge.setConnected(CpsEdge.CON_UPPER_NODE_NOT_INSIDE);
+					checkForConnectedStates(b, (CpsUpperNode) a, edge);
+				}
+				if (b instanceof CpsUpperNode && b.getId() != cps.getId()) {
+					edge.setConnected(CpsEdge.CON_UPPER_NODE_NOT_INSIDE);
+					checkForConnectedStates(a, (CpsUpperNode) b, edge);
+				}
+			} else {
+				brokenEdges.add(edge);
+			}
+		}
+		return sN;
+	}
+
+	/**
+	 * is the Switch in a legitimate State.
+	 *
+	 * @param current
+	 *            AbstractCpsObject
+	 * @return boolean
+	 */
+	private boolean legitState(AbstractCpsObject current) {
+		return !(current instanceof HolonSwitch)
+				|| ((HolonSwitch) current).getState(timeStep);
+	}
+
+	// /**
+	// * ensures that objectsToHandle only contains HolonObjects.
+	// */
+	// public void cleanObjectsToHandle() {
+	// for (int i = 0; i < objectsToHandle.size(); i++) {
+	// if (!(objectsToHandle.get(i) instanceof HolonObject)) {
+	// objectsToHandle.remove(i);
+	// }
+	// }
+	// }
+
+	/**
+	 * removes an Object that already has been handled.
+	 *
+	 * @param id
+	 *            the Object ID
+	 */
+	private void removeFromToHandle(int id) {
+		for (int i = 0; i < objectsToHandle.size(); i++) {
+			if (objectsToHandle.get(i).getId() == id) {
+				objectsToHandle.remove(i);
+			}
+		}
+	}
+
+	/**
+	 * copies the data of an array of Objects.
+	 *
+	 * @param toCopy
+	 *            the ArrayList of CpsObjects co Copy
+	 */
+	private void copyObjects(ArrayList<AbstractCpsObject> toCopy) {
+		for (AbstractCpsObject cps : toCopy) {
+			if (cps instanceof CpsUpperNode) {
+				copyObjects(((CpsUpperNode) cps).getNodes());
+			} else {
+				objectsToHandle.add(cps);
+			}
+		}
+	}
+
+	/**
+	 * Prints the Components auf all subnets.
+	 */
+	private void printNetsToConsole() {
+		for (int i = 0; i < subNets.size(); i++) {
+			SubNet subNet = subNets.get(i);
+			System.out.println("SUBNET NR:" + i);
+			subNet.toString(timeStep);
+		}
+	}
+
+	/**
+	 * Set the Canvas.
+	 *
+	 * @param can
+	 *            the Canvas
+	 */
+	public void setCanvas(MyCanvas can) {
+		canvas = can;
+	}
+
+	/**
+	 * Reset all Data to the current state of the Model.
+	 */
+	public void reset() {
+		objectsToHandle = new ArrayList<>();
+		copyObjects(model.getObjectsOnCanvas());
+		flexDevicesTurnedOnThisTurn = new HashMap<>();
+	}
+
+	/**
+	 * Resets the State of all Edges
+	 */
+	private void resetEdges() {
+		for (CpsEdge e : brokenEdges) {
+			e.setWorkingState(true);
+		}
+	}
+
+	/**
+	 * Resets the State for the whole Simulation Model
+	 */
+	void resetSimulation() {
+		reset();
+		resetEdges();
+	}
+
+	/**
+	 * Get all Subnets.
+	 *
+	 * @return all Subnets
+	 */
+	public ArrayList<SubNet> getSubNets() {
+		return subNets;
+	}
+
+	/**
+	 * Get broken Edges
+	 */
+	// public ArrayList<CpsEdge> getBrokenEdges() {
+	// return brokenEdges;
+	// }
+
+	/**
+	 * checks whether a given object is connected to an object inside the
+	 * upperNode. if yes, the state for the edge is changed in "connected" or
+	 * "not connected"
+	 */
+	private void checkForConnectedStates(AbstractCpsObject cps,
+			CpsUpperNode cUNode, CpsEdge theEdge) {
+		AbstractCpsObject tmp;
+		for (CpsEdge edge : cps.getConnections()) {
+			if (edge.getA().getId() == cps.getId()) {
+				tmp = edge.getB();
+			} else {
+				tmp = edge.getA();
+			}
+			if (cUNode.getNodes().contains(tmp)) {
+				if (tmp instanceof CpsUpperNode) {
+					checkForConnectedStates(cps, (CpsUpperNode) tmp, theEdge);
+				} else {
+					theEdge.setConnected(CpsEdge.CON_UPPER_NODE_AND_INSIDE);
+					break;
+				}
+			}
+		}
+	}
+
+	public FlexiblePane getFlexiblePane() {
+		return flexPane;
+	}
+
+	void setFlexiblePane(FlexiblePane fp) {
+		flexPane = fp;
+	}
 
 }

+ 18 - 1
src/ui/model/Model.java

@@ -67,8 +67,11 @@ public class Model {
     private boolean showConsoleLog = true;
     // whether the console log of the program should be displayed
     private boolean useFlexibleDevices = true;
-    // whether the supplyBars should be shown or not
+    /** whether the supplyBars should be shown or not */
     private boolean showSupplyBars = true;
+    
+    /** the Fairness model in use */
+    private short fairnessModel = 0;
     /*
      * Array of all categories in the model. It is set by default with the
      * categories ENERGY, BUILDINGS and COMPONENTS
@@ -919,6 +922,20 @@ public class Model {
 	public void setShowSupplyBars(boolean showSupplyBars) {
 		this.showSupplyBars = showSupplyBars;
 	}
+	
+	/**
+	 * @return the fairnessModel
+	 */
+	public short getFairnessModel() {
+		return fairnessModel;
+	}
+	
+	/**
+	 * @param fairnessModel the fairnessModel to set
+	 */
+	public void setFairnessModel(short fairnessModel) {
+		this.fairnessModel = fairnessModel;
+	}
 
 	/**
      * Initialize the Gson with wanted parameters

+ 2610 - 2276
src/ui/view/GUI.java

@@ -1,12 +1,17 @@
 package ui.view;
 
 import classes.*;
+
 import com.google.gson.JsonNull;
 import com.google.gson.JsonObject;
 import com.google.gson.JsonParseException;
+
 import interfaces.CategoryListener;
+
 import org.apache.commons.compress.archivers.ArchiveException;
+
 import ui.controller.Control;
+import ui.controller.SimulationManager;
 import ui.controller.UpdateController;
 import ui.model.Model;
 
@@ -19,6 +24,7 @@ import javax.swing.table.TableCellRenderer;
 import javax.swing.tree.DefaultMutableTreeNode;
 import javax.swing.tree.DefaultTreeModel;
 import javax.swing.tree.TreeCellRenderer;
+
 import java.awt.*;
 import java.awt.datatransfer.UnsupportedFlavorException;
 import java.awt.event.*;
@@ -37,2295 +43,2623 @@ import java.util.stream.Collectors;
  */
 public class GUI implements CategoryListener {
 
-    private final AlgorithmMenu algorithmMenu;
-    private final JMenuBar menuBar = new JMenuBar();
-    private final JMenu mnNewMenu = new JMenu("File");
-    private final JMenu mnNewMenuEdit = new JMenu("Edit");
-    private final JMenu mnNewMenuOptions = new JMenu("Options");
-    private final JMenu mnNewMenuView = new JMenu("View");
-    private final JMenu mnHelp = new JMenu("Help");
-    private final JCheckBox consoleLogCheckBox = new JCheckBox("Show program console log");
-    private final JCheckBox useFlexibleDevicesCheckBox = new JCheckBox("Automatically use flexible devices");
-    private final JCheckBox showSupplyBarsCheckBox = new JCheckBox("Show supply bars.");
-    private final JMenuItem mntmOpen = new JMenuItem("Open");
-    private final JMenuItem mntmNew = new JMenuItem("New");
-    private final JMenuItem mntmSave = new JMenuItem("Save");
-    private final JMenuItem mntmAboutUs = new JMenuItem("About Us");
-    private final JMenuItem mntmCanvasSize = new JMenuItem("View Size");
-    private final JMenuItem mntmBackground = new JMenuItem("Background Image");
-    private final JMenuItem mntmSplitView = new JMenuItem("Split View");
-    private final JSplitPane splitPane = new JSplitPane();
-    private final JSplitPane splitPane1 = new JSplitPane();
-    private final JSplitPane splitPaneCanvasConsole = new JSplitPane(JSplitPane.VERTICAL_SPLIT);
-    // the tabbed canvas containing the different sub-net tabs of the grid (Main Grid + Nodes of Nodes)
-    private final JTabbedPane tabbedPaneInnerOriginal = new JTabbedPane(JTabbedPane.TOP);
-    // the main canvas where we can see the grid currently displayed
-    private final JScrollPane canvasSP = new JScrollPane();
-    private final JScrollPane scrollPane1 = new JScrollPane();
-    // private final JScrollPane holonSP = new JScrollPane();
-    // the original tabbed Pane (containing tabs for view, statistics, holon, flexibility)
-    private final JTabbedPane tabbedPaneOriginal = new JTabbedPane(JTabbedPane.TOP);
-    // the same tabbed Pane that appears once the view is split
-    private final JTabbedPane tabbedPaneSplit = new JTabbedPane(JTabbedPane.TOP);
-    private final JPopupMenu popmenuEdit = new JPopupMenu();
-    private final JMenuItem editItem = new JMenuItem("Edit Object");
-    private final StatisticPanel statSplitPane;
-    private final JScrollPane statScrollPane;
-    private final JLabel maxGraph = new JLabel("100%");
-    private final JLabel medGraph = new JLabel("50%");
-    private final JLabel minGraph = new JLabel("0%");
-    private final JLabel elementGraph = new JLabel("None ");
-    private final ArrayList<HolonElement> selectedElements = new ArrayList<>();
-    private final JTree tree = new JTree();
-    /******************************************
-     ************* Right Container*************
-     ******************************************
-     * Right Container: here comes the information about the HolonObject, such
-     * as HolonElements Information, Properties and Consumption/Production
-     * graph.
-     **/
-    private final JSplitPane splitHolonElPro = new JSplitPane(JSplitPane.VERTICAL_SPLIT);
-    private final JSplitPane splitGraphHolonEl = new JSplitPane(JSplitPane.VERTICAL_SPLIT);
-    private final int distanceBetweenElementsAndGraph = 350;
-    // Model for single or multi selection
-    private final JPanel scrollElements = new JPanel();
-    private final JScrollPane tableHolonElementScrollPane = new JScrollPane();
-    // In this section are all the properties that correspond to the clicked
-    // HolonObject, such as connections, name, Type, etc.
-    // Table for Properties --> Cell with (0,1) is editable by CpsObjt and
-    // Cell(3,1) is editable by Edges
-    private final JTable tableProperties = new JTable() {
-
-        private static final long serialVersionUID = 1L;
-
-        @Override
-        public TableCellRenderer getCellRenderer(int row, int column) {
-            if (getValueAt(row, column) instanceof Boolean) {
-                return super.getDefaultRenderer(Boolean.class);
-            } else {
-                return super.getCellRenderer(row, column);
-            }
-        }
-
-        @Override
-        public TableCellEditor getCellEditor(int row, int column) {
-            if (getValueAt(row, column) instanceof Boolean) {
-                return super.getDefaultEditor(Boolean.class);
-            } else {
-                return super.getCellEditor(row, column);
-            }
-        }
-    };
-    private final JPanel graphLabel = new JPanel();
-    private final JScrollPane scrollProperties = new JScrollPane();
-    // In this section is the graph for the selected HolonElement of the clicked
-    // HolonObject
-    private final JTable tableGraph = new JTable();
-    private final DefaultTableModel tableModelGraph = new DefaultTableModel();
-    private final JScrollPane scrollGraph = new JScrollPane();
-    private final Model model;
-    private final Control controller;
-
-    // In this section are all the Holonelements that correspond to the clicked
-    // HolonObject with consumption/production, name and amount.
-    private final JPanel panel = new JPanel();
-    private final JPanel panelHolonEl = new JPanel();
-    private final JComboBox comboBox = new JComboBox();
-    // Buttons
-    private final JButton btnAdd = new JButton("+");
-    private final JButton btnDel = new JButton("-");
-    private final JButton btnAddHolEL = new JButton("+");
-    private final JButton btnDelHolEL = new JButton("-");
-    private final JButton resetGraphBtn = new JButton("Reset");
-    private final JToolBar toolBar = new JToolBar();
-    private final JToolBar toolBarHolonEl = new JToolBar();
-    private final JToolBar toolBarGraph = new JToolBar();
-    // Languages
-    private final JMenuItem englishBtn = new JMenuItem("EN");
-    private final JMenuItem spanishBtn = new JMenuItem("ES");
-    private final JMenuItem germanBtn = new JMenuItem("DE");
-    private final JMenuItem czechBtn = new JMenuItem("CZ");
-    private final JMenuItem chineseBtn = new JMenuItem("ZH");
-    // private final JComboBox comboBoxGraph = new JComboBox();
-    private final Console console = new Console();
-    private final MyCanvas canvas;
-    private final HolonCanvas holonCanvas;
-    private final UnitGraph unitGraph;
-    private final JSplitPane splitPane3 = new JSplitPane();
-    private final JSlider sizeSlider = new JSlider();
-    private final JLabel lblImageSize = new JLabel(Languages.getLanguage()[94]);
-    private final JMenuItem mntmUndo = new JMenuItem("Undo");
-    private final JMenuItem mntmRedo = new JMenuItem("Redo");
-    private final JMenuItem mntmEditEdges = new JMenuItem("Edge Properties");
-    private final JMenuItem mntmFindReplace = new JMenuItem("Find/ Replace");
-    private final JMenuItem mntmEditShowedInformation = new JMenuItem("Edit showed Information");
-    private final JMenuItem mntmResetCategory = new JMenuItem("Reset Categories");
-    private final JMenu mnLanguage = new JMenu("Language");
-    private final String[] columnNamesMulti = {"Object", "Nr.", "Device", "Energy", "Flexible Energy Available",
-            "Quantity", "Activated", "Flexible"};
-    private final String[] columnNamesSingle = {"Nr.", "Device", "Energy", "Flexible Energy Available", "Quantity",
-            "Activated", "Flexible"};
-    private final ArrayList<PropertyTable> tables = new ArrayList<>();
-    private final String[] comboBoxCat = {"Category", "Object", "Switch"};
-    private final UpdateController updCon;
-    private final JSplitPane splitPane_1 = new JSplitPane();
-    private final JSlider holonBodySizeSlider = new JSlider();
-    private final JLabel lblHolonBodySize = new JLabel("HolonBody SIze");
-    private final JLabel lblSelectedElement = new JLabel("Selected Element: ");
-    // for doubleclick
-    private boolean click = false;
-    private JFrame frmCyberPhysical;
-    private JTabbedPane tabTemp; // tabbedPaneOriginal or tabbedPaneSplit
-    private JSplitPane tempSplit;
-    private boolean initSplit = true;
-    private String catOfObjToBeEdited;
-    private UpperNodeCanvas unc;
-    private JPanel contentPane;
-    private String holonEleNamesDisplayed = "None ";
-    // Pop up Windows
-    private AddObjectPopUp addObjectPopUP;
-    private AboutUsPopUp aboutUsPopUp;
-    private AddElementPopUp addElementPopUp;
-    // variables
-    private boolean dragging = false;
-    private String actualObjectClicked;
-    private Image img = null;
-    private AbstractCpsObject tempCps = null;
-    private int yValueElements = 0;
-    // Time Stuff
-    private TimePanel timePanel;
-    // Coord for all Cells with text
-    private int yThis;
-    private int xThis;
-    // Coord for all Cells with boolean values (checkbox)
-    private int yBTis;
-    private int xBThis;
-    // Coord for the Edit-Modus in the PropertieTable
-    private int yProThis;
-    private int xProThis;
-    private int yProThisOneClick;
-    private int xProThisOneClick;
-    private AbstractCpsObject temp = null;
-    private String warningText = "Warning";
-    private String saveBeforeNew = "Do you want to save your current data?";
-    private String eraseCategory = "Do you really want to delete the Category ";
-    private String selectObjBeforeErase = "Please select a Category or an Object in order to delete something.";
-
-    /**
-     * Create the application.
-     *
-     * @param control the Controller
-     */
-    GUI(Control control) {
-        this.controller = control;
-        this.model = control.getModel();
-        statSplitPane = new StatisticPanel(controller);
-        model.addGraphListener(statSplitPane);
-        model.setStatPanel(statSplitPane);
-        statScrollPane = new JScrollPane(statSplitPane);
-        this.unitGraph = new UnitGraph(model, control);
-        this.canvas = new MyCanvas(model, control, unitGraph);
-        this.holonCanvas = new HolonCanvas(model, control);
-
-        control.initListener(this);
-        controller.setCanvas(canvas);
-        model.setConsole(console);
-        algorithmMenu = new AlgorithmMenu(model, control, this);
-        initialize();
-        updateCategories(model.getCategories());
-        updCon = new UpdateController(model, controller);
-    }
-
-//    /**
-//     * Adds a Popup.
-//     *
-//     * @param component Component
-//     * @param popup     PopupMenu
-//     */
-//    private static void addPopup(Component component, final JPopupMenu popup) {
-//        component.addMouseListener(new MouseAdapter() {
-//            public void mousePressed(MouseEvent e) {
-//                if (e.isPopupTrigger()) {
-//                    showMenu(e);
-//                }
-//            }
-//
-//            public void mouseReleased(MouseEvent e) {
-//                if (e.isPopupTrigger()) {
-//                    showMenu(e);
-//                }
-//            }
-//
-//            private void showMenu(MouseEvent e) {
-//                popup.show(e.getComponent(), e.getX(), e.getY());
-//            }
-//
-//        });
-//    }
-
-    /**
-     * Initialize the contents of the frame.
-     */
-    @SuppressWarnings({"serial", "unchecked"})
-    private void initialize() {
-        frmCyberPhysical = new JFrame();
-        frmCyberPhysical.setTitle("Cyber Physical Systems Model");
-        // try to restore old position/dimensions
-        ArrayList<Integer> savedWindowDim = controller.loadSavedWindowDimensionsIfExistent();
-        if (savedWindowDim.size() == 4) {
-            frmCyberPhysical.setBounds(savedWindowDim.get(0), savedWindowDim.get(1),
-                    savedWindowDim.get(2), savedWindowDim.get(3));
-        }
-
-        // if the upper part of the window is showing, the windows can still be moved,
-        // but if it is not, we need to move it to somewhere else
-        if (savedWindowDim.size() != 4 || !isUpperPanelInsideBounds()) {
-            frmCyberPhysical.setBounds(100, 100, 1000, 800);
-            frmCyberPhysical.setExtendedState(JFrame.MAXIMIZED_BOTH);
-        }
-        frmCyberPhysical.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
-
-        frmCyberPhysical.addWindowListener(new java.awt.event.WindowAdapter() {
-            @Override
-            public void windowClosing(java.awt.event.WindowEvent windowEvent) {
-                if (JOptionPane.showConfirmDialog(frmCyberPhysical, Languages.getLanguage()[88],
-                        "Cyber Physical Systems Model", JOptionPane.YES_NO_OPTION,
-                        JOptionPane.QUESTION_MESSAGE) == JOptionPane.YES_OPTION) {
-                    controller.deleteDirectory(new File(System.getProperty("user.home")
-                            + "/.config/HolonGUI/Autosave"));
-
-                    // try to save the position and size of the window, such that (if possible)
-                    // it can be opened in the same position the next time
-                    try {
-                        controller.savePosAndSizeOfWindow(frmCyberPhysical.getX(), frmCyberPhysical.getY(),
-                                frmCyberPhysical.getWidth(), frmCyberPhysical.getHeight());
-                    } catch (Exception e) {
-                        e.printStackTrace();
-                    }
-                    System.exit(0);
-                }
-            }
-        });
-
-        contentPane = (JPanel) frmCyberPhysical.getContentPane();
-
-        int condition = JComponent.WHEN_IN_FOCUSED_WINDOW;
-        InputMap inputMap = contentPane.getInputMap(condition);
-        ActionMap actionMap = contentPane.getActionMap();
-
-        String cntrlZDown = "controlZ";
-        inputMap.put(KeyStroke.getKeyStroke("control Z"), cntrlZDown);
-        actionMap.put(cntrlZDown, new AbstractAction() {
-
-            private static final long serialVersionUID = 1L;
-
-            @Override
-            public void actionPerformed(ActionEvent e) {
-                try {
-                    controller.loadAutoSave(controller.getUndoSave());
-                    canvas.repaint();
-                    unitGraph.update(model.getObjectsOnCanvas());
-                    updateUpperNodes();
-                } catch (IOException eex) {
-                    eex.printStackTrace();
-                }
-            }
-        });
-
-        String cntrlYDown = "controlY";
-        inputMap.put(KeyStroke.getKeyStroke("control Y"), cntrlYDown);
-        actionMap.put(cntrlYDown, new AbstractAction() {
-
-            private static final long serialVersionUID = 1L;
-
-            @Override
-            public void actionPerformed(ActionEvent e) {
-                try {
-                    controller.loadAutoSave(controller.getRedoSave());
-                    canvas.repaint();
-                    unitGraph.update(model.getObjectsOnCanvas());
-                    updateUpperNodes();
-                } catch (IOException ex) {
-                    ex.printStackTrace();
-                }
-            }
-        });
-
-        String cntrlADown = "controlA";
-        inputMap.put(KeyStroke.getKeyStroke("control A"), cntrlADown);
-        AbstractAction controlA = new AbstractAction() {
-            private static final long serialVersionUID = 1L;
-
-            @Override
-            public void actionPerformed(ActionEvent e) {
-                chooseTabTemp();
-
-                model.getSelectedCpsObjects().clear();
-
-                // Uppernode Canvas?
-                JScrollPane scrollPane = getScrollPaneFromTabbedPane();
-                Component canvasOrUpperNodeCanvas = scrollPane.getViewport().getComponent(0);
-
-                if (canvasOrUpperNodeCanvas instanceof UpperNodeCanvas) {
-                    UpperNodeCanvas uNC = (UpperNodeCanvas) canvasOrUpperNodeCanvas;
-                    for (AbstractCpsObject cps : uNC.upperNode.getNodes()) {
-                        controller.addSelectedObject(cps);
-                    }
-                    uNC.repaint();
-                    // or Canvas?
-                } else if (canvasOrUpperNodeCanvas instanceof MyCanvas) {
-                    for (AbstractCpsObject cps : model.getObjectsOnCanvas()) {
-                        controller.addSelectedObject(cps);
-                    }
-                    canvas.repaint();
-                }
-                controller.getObjectsInDepth();
-
-            }
-        };
-        actionMap.put(cntrlADown, controlA);
-
-        String delDown = "delete";
-        inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_DELETE, 0, false), delDown);
-        actionMap.put(delDown, new AbstractAction() {
-
-            private static final long serialVersionUID = 1L;
-
-            @Override
-            public void actionPerformed(ActionEvent e) {
-                chooseTabTemp();
-
-                // Uppernode Canvas?
-                JScrollPane scrollPane = getScrollPaneFromTabbedPane();
-                Component canvasOrUpperNodeCanvas = scrollPane.getViewport().getComponent(0);
-
-                // check whether a producer was deleted (this triggers a complete re-evaluation of the net)
-                boolean wasProducerDeleted = false;
-
-                if (canvasOrUpperNodeCanvas instanceof UpperNodeCanvas) {
-                    UpperNodeCanvas uNC = (UpperNodeCanvas) canvasOrUpperNodeCanvas;
-                    for (AbstractCpsObject cps : model.getSelectedCpsObjects()) {
-
-                        if (cps instanceof HolonObject
-                                && ((HolonObject) cps).getState() == HolonObject.PRODUCER) {
-                            wasProducerDeleted = true;
-                        }
-
-                        controller.removeTrackingObj(cps);
-                        if (uNC.upperNode.getNodes().contains(cps)) {
-                            controller.delObjUpperNode(cps, uNC.upperNode);
-                            unc.setToolTip(false);
-
-                            // remove UpperNodeTab if UpperNode deleted
-                            removeUpperNodeTab(cps);
-                        }
-                    }
-                    uNC.repaint();
-
-                    // or Canvas?
-                } else if (canvasOrUpperNodeCanvas instanceof MyCanvas) {
-                    boolean save = false;
-                    CpsEdge edgeHighlight= model.getSelectedEdge();
-                    if(edgeHighlight != null){
-                    	controller.removeEdgesOnCanvas(edgeHighlight);
-                    	((MyCanvas) canvasOrUpperNodeCanvas).edgeHighlight = null;
-                    }
-                    for (int j = 0; j < model.getSelectedCpsObjects().size(); j++) {
-                        AbstractCpsObject cps = model.getSelectedCpsObjects().get(j);
-
-                        if (cps instanceof HolonObject
-                                && ((HolonObject) cps).getState() == HolonObject.PRODUCER) {
-                            wasProducerDeleted = true;
-                        }
-
-                        controller.removeTrackingObj(cps);
-                        if (j < model.getSelectedCpsObjects().size() - 1)
-                            save = true;
-                        controller.delCanvasObject(cps, save);
-                        canvas.setToolTip(false);
-
-                        // remove UpperNodeTab if UpperNode deleted
-                        removeUpperNodeTab(cps);
-                    }
-                    canvas.repaint();
-                }
-
-                // recalculate net if a producer was deleted
-                if (wasProducerDeleted) {
-                    controller.resetSimulation();
-                    controller.calculateStateForCurrentTimeStep();
-                }
-
-                model.getSelectedCpsObjects().clear();
-                hideScrollGraph();
-            }
-        });
-
-        String cntrlFDown = "controlF";
-        inputMap.put(KeyStroke.getKeyStroke("control F"), cntrlFDown);
-        actionMap.put(cntrlFDown, new AbstractAction() {
-
-            private static final long serialVersionUID = 1L;
-
-            @Override
-            public void actionPerformed(ActionEvent e) {
-                SearchPopUp dialog = new SearchPopUp(controller, canvas, frmCyberPhysical);
-                dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
-                dialog.setVisible(true);
-            }
-        });
-
-        String cntrlCDown = "controlC";
-        inputMap.put(KeyStroke.getKeyStroke("control C"), cntrlCDown);
-        AbstractAction controlC = new AbstractAction() {
-            private static final long serialVersionUID = 1L;
-
-            @Override
-            public void actionPerformed(ActionEvent e) {
-                chooseTabTemp();
-
-                JScrollPane scrollPane = getScrollPaneFromTabbedPane();
-                if (!model.getSelectedCpsObjects().isEmpty()) {
-                    if (scrollPane.getViewport().getComponent(0) instanceof UpperNodeCanvas)
-                        controller.copy(((UpperNodeCanvas) scrollPane.getViewport().getComponent(0)).upperNode);
-                    else
-                        controller.copy(null);
-                    if (!model.getClipboradObjects().isEmpty()) {
-                        canvas.itemPaste.setEnabled(true);
-                    }
-                }
-            }
-        };
-        actionMap.put(cntrlCDown, controlC);
-
-        String cntrlVDown = "controlV";
-        inputMap.put(KeyStroke.getKeyStroke("control V"), cntrlVDown);
-        AbstractAction controlV = new AbstractAction() {
-            private static final long serialVersionUID = 1L;
-
-            @Override
-            public void actionPerformed(ActionEvent e) {
-                try {
-                    tabTemp = null;
-                    if (tabbedPaneOriginal.getMousePosition() != null) {
-                        tabTemp = tabbedPaneOriginal;
-                    } else {
-                        if (!initSplit) {
-                            tabTemp = tabbedPaneSplit;
-                        }
-                    }
-
-                    JScrollPane scrollPane = getScrollPaneFromTabbedPane();
-                    Component canvasOrUpperNodeCanvas = scrollPane.getViewport().getComponent(0);
-
-                    if (tabTemp != null && canvasOrUpperNodeCanvas instanceof UpperNodeCanvas) {
-
-                        controller.paste(
-                                ((UpperNodeCanvas) canvasOrUpperNodeCanvas).upperNode,
-                                canvasOrUpperNodeCanvas.getMousePosition());
-                        unitGraph.update(model.getSelectedCpsObjects());
-                        scrollPane.getViewport().getComponent(0).repaint();
-                    } else {
-                        controller.paste(null, canvas.getMousePosition());
-                        unitGraph.update(model.getSelectedCpsObjects());
-                        canvas.repaint();
-                    }
-                } catch (HeadlessException | JsonParseException | UnsupportedFlavorException | IOException e1) {
-                    JLabel message = new JLabel("The Clipboard information cannot be pasted into Application.");
-                    JOptionPane.showMessageDialog(frmCyberPhysical, message, "", JOptionPane.ERROR_MESSAGE);
-                }
-
-            }
-        };
-        actionMap.put(cntrlVDown, controlV);
-
-        String cntrlXDown = "controlX";
-        inputMap.put(KeyStroke.getKeyStroke("control X"), cntrlXDown);
-        AbstractAction controlX = new AbstractAction() {
-            private static final long serialVersionUID = 1L;
-
-            @Override
-            public void actionPerformed(ActionEvent e) {
-                chooseTabTemp();
-
-                JScrollPane scrollPane = getScrollPaneFromTabbedPane();
-                if (!model.getSelectedCpsObjects().isEmpty()) {
-                    if (scrollPane.getViewport().getComponent(0) instanceof UpperNodeCanvas) {
-                        controller.cut(((UpperNodeCanvas) scrollPane.getViewport().getComponent(0)).upperNode);
-                    } else {
-                        controller.cut(null);
-                    }
-                    if (!model.getClipboradObjects().isEmpty()) {
-                        canvas.itemPaste.setEnabled(true);
-                    }
-                    canvas.repaint();
-                }
-            }
-        };
-        actionMap.put(cntrlXDown, controlX);
-
-        frmCyberPhysical.setJMenuBar(menuBar);
-
-        frmCyberPhysical.setIconImage(Util.loadImage(this,"/Images/Dummy_House.png",30,30));
-        		
-        menuBar.add(mnNewMenu);
-
-        mnNewMenu.add(mntmNew);
-
-        mnNewMenu.add(mntmOpen);
-
-        mnNewMenu.add(mntmSave);
-
-        menuBar.add(mnNewMenuEdit);
-
-        mnNewMenuEdit.add(mntmUndo);
-
-        mnNewMenuEdit.add(mntmRedo);
-
-        mnLanguage.add(englishBtn);
-        englishBtn.setIcon(new ImageIcon(new ImageIcon("res/Button_Images/FlagEN.png").getImage().getScaledInstance(20,
-                20, java.awt.Image.SCALE_SMOOTH)));
-        mnLanguage.add(spanishBtn);
-        spanishBtn.setIcon(new ImageIcon(new ImageIcon("res/Button_Images/FlagES.png").getImage().getScaledInstance(20,
-                20, java.awt.Image.SCALE_SMOOTH)));
-        mnLanguage.add(germanBtn);
-        germanBtn.setIcon(new ImageIcon(new ImageIcon("res/Button_Images/FlagDE.png").getImage().getScaledInstance(20,
-                20, java.awt.Image.SCALE_SMOOTH)));
-        // mnLanguage.add(czechBtn);
-        // czechBtn.setIcon(new ImageIcon(new
-        // ImageIcon("res/Button_Images/FlagCZ.png").getImage().getScaledInstance(20,
-        // 20, java.awt.Image.SCALE_SMOOTH)));
-        mnLanguage.add(chineseBtn);
-        chineseBtn.setIcon(new ImageIcon(new ImageIcon("res/Button_Images/FlagZH.png").getImage().getScaledInstance(20,
-                20, java.awt.Image.SCALE_SMOOTH)));
-
-        mntmFindReplace.addActionListener(actionEvent -> {
-            try {
-                SearchPopUp dialog = new SearchPopUp(controller, canvas, frmCyberPhysical);
-                dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
-                dialog.setVisible(true);
-                controller.getObjectsInDepth();
-            } catch (Exception ex) {
-                ex.printStackTrace();
-            }
-        });
-
-        mnNewMenuEdit.add(mntmFindReplace);
-        mntmEditShowedInformation.addActionListener(actionEvent -> {
-            try {
-                DisplayedInformationPopUp dialog = new DisplayedInformationPopUp(canvas, contentPane, controller, frmCyberPhysical);
-                dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
-                dialog.setVisible(true);
-            } catch (Exception ex) {
-                ex.printStackTrace();
-            }
-        });
-
-        mnNewMenuEdit.add(mntmEditShowedInformation);
-        mnNewMenuEdit.add(mntmEditEdges);
-        mntmEditEdges.addActionListener(actionEvent -> {
-            EditEdgesPopUp edgePopUp = new EditEdgesPopUp(frmCyberPhysical);
-            edgePopUp.setCanvas(canvas);
-            edgePopUp.setController(controller);
-            edgePopUp.setVisible(true);
-        });
-
-        menuBar.add(mnNewMenuOptions);
-
-        mnNewMenuOptions.add(mntmResetCategory);
-        mntmResetCategory.addActionListener(actionEvent -> {
-            ArrayList<Category> cat = model.getCategories();
-            try {
-                while (!cat.isEmpty()) {
-                    controller.deleteCategory(cat.get(0).getName());
-
-                }
-                controller.resetCategorys();
-            } catch (Exception e2) {
-            }
-
-            tree.repaint();
-        });
-        mnNewMenuOptions.add(consoleLogCheckBox);
-        consoleLogCheckBox.setSelected(true);
-        consoleLogCheckBox.addActionListener(arg0 -> controller.setShowConsoleLog(consoleLogCheckBox.isSelected()));
-
-        mnNewMenuOptions.add(useFlexibleDevicesCheckBox);
-        useFlexibleDevicesCheckBox.setSelected(true);
-        useFlexibleDevicesCheckBox.addActionListener(
-                actionEvent -> model.setUseFlexibleDevices(useFlexibleDevicesCheckBox.isSelected()));
-
-        menuBar.add(mnNewMenuView);
-
-        mnNewMenuView.add(mntmCanvasSize);
-        mntmCanvasSize.addActionListener(actionEvent -> {
-            CanvasResizePopUp popUp = new CanvasResizePopUp(model, controller, canvas, tabbedPaneOriginal, tabbedPaneSplit, frmCyberPhysical);
-            popUp.setVisible(true);
-        });
-
-        mnNewMenuView.add(splitPane3);
-
-        sizeSlider.setMinimum(15);
-        sizeSlider.setMaximum(115);
-        sizeSlider.addChangeListener(changeEvent -> {
-            controller.setScale(sizeSlider.getValue());
-
-            JScrollPane scrollPane = getScrollPaneFromTabbedPane();
-
-            if (scrollPane.getViewport()
-                    .getComponent(0) instanceof UpperNodeCanvas) {
-                scrollPane.getViewport().getComponent(0).repaint();
-            } else {
-                canvas.repaint();
-            }
-            if (!initSplit && scrollPane.getViewport().getComponent(0) instanceof UpperNodeCanvas) {
-                scrollPane.getViewport().getComponent(0).repaint();
-            } else {
-                canvas.repaint();
-            }
-        });
-
-        mnNewMenuView.add(mntmCanvasSize);
-        mnNewMenuView.add(mntmSplitView);
-
-        /*
-         * Adds Checkbox to turn supply bars on/off
-         */
-        mnNewMenuView.add(showSupplyBarsCheckBox);
-        showSupplyBarsCheckBox.setSelected(true);
-        showSupplyBarsCheckBox.addActionListener(arg0 -> {
-        controller.setShowSupplyBars(showSupplyBarsCheckBox.isSelected());
-        canvas.repaint();      
-        });
-        
-        // Split View
-        mntmSplitView.addActionListener(actionEvent -> {
-            if (splitPaneCanvasConsole.getLeftComponent() instanceof JSplitPane) {
-                initSplit = true;
-                Component tempC = tabbedPaneSplit.getSelectedComponent();
-                tabbedPaneOriginal.setComponentAt(tabbedPaneSplit.getSelectedIndex(), tempC);
-                tabbedPaneSplit.removeAll();
-                splitPaneCanvasConsole.setLeftComponent(tabbedPaneOriginal);
-            } else {
-                for (int i = 0; i < tabbedPaneOriginal.getTabCount(); i++) {
-                    // add outer tabs
-                    // (inner tabs are added by tabbedPaneSplit changelistener)
-                    tabbedPaneSplit.addTab(tabbedPaneOriginal.getTitleAt(i), null);
-                }
-                if (tabbedPaneOriginal.getSelectedComponent() == statScrollPane) {
-                    tabbedPaneOriginal.setComponentAt(0, null);
-                    tabbedPaneSplit.setComponentAt(0, canvasSP);
-                    tabbedPaneSplit.setSelectedIndex(0);
-                } else {
-                    tabbedPaneOriginal.setComponentAt(1, null);
-                    tabbedPaneSplit.setComponentAt(1, statScrollPane);
-                    tabbedPaneSplit.setSelectedIndex(1);
-                }
-                tempSplit = new JSplitPane();
-                tempSplit.setBorder(null);
-                tempSplit.setRightComponent(tabbedPaneSplit);
-                tempSplit.setLeftComponent(tabbedPaneOriginal);
-                tempSplit.setDividerLocation(tabbedPaneOriginal.getWidth() / 2);
-                tempSplit.setResizeWeight(0.9);
-                splitPaneCanvasConsole.setLeftComponent(tempSplit);
-                initSplit = false;
-            }
-            contentPane.updateUI();
-        });
-        mnNewMenuView.add(mntmBackground);
-
-        mntmBackground.addActionListener(actionEvent -> {
-            tabTemp = tabbedPaneOriginal;
-            JScrollPane scrollPane = getScrollPaneFromTabbedPane();
-
-            if (scrollPane.getViewport().getComponent(0) instanceof MyCanvas) {
-                BackgroundPopUp backgroundDialog = new BackgroundPopUp(model, controller, canvas, null, frmCyberPhysical);
-                backgroundDialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
-                backgroundDialog.setVisible(true);
-            } else if (scrollPane.getViewport().getComponent(0) instanceof UpperNodeCanvas) {
-                UpperNodeCanvas uNodeCanvas = (UpperNodeCanvas) (scrollPane.getViewport().getComponent(0));
-                BackgroundPopUp backgroundDialog = new BackgroundPopUp(model, controller, null,
-                        uNodeCanvas.upperNode, frmCyberPhysical);
-                backgroundDialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
-                backgroundDialog.setVisible(true);
-                uNodeCanvas.repaint();
-            }
-        });
-
-        splitPane3.setRightComponent(sizeSlider);
-
-        splitPane3.setLeftComponent(lblImageSize);
-
-        mnNewMenuView.add(splitPane_1);
-        holonBodySizeSlider.setValue(100);
-        holonBodySizeSlider.setMinimum(1);
-
-        holonBodySizeSlider.addChangeListener(changeEvent -> {
-            controller.setHolonBodyScale(holonBodySizeSlider.getValue());
-            tree.setRowHeight(50);
-            canvas.repaint();
-        });
-
-        splitPane_1.setRightComponent(holonBodySizeSlider);
-
-        splitPane_1.setLeftComponent(lblHolonBodySize);
-
-        menuBar.add(algorithmMenu);
-
-        menuBar.add(mnHelp);
-
-        mnHelp.add(mntmAboutUs);
-
-        tabbedPaneOriginal.addChangeListener(changeEvent -> {
-            if (tabbedPaneOriginal.getSelectedComponent() == null) {
-                Component tempC = tabbedPaneSplit.getSelectedComponent();
-                tabbedPaneSplit.setComponentAt(tabbedPaneOriginal.getSelectedIndex(), null);
-                tabbedPaneOriginal.setComponentAt(tabbedPaneOriginal.getSelectedIndex(), tempC);
-                tempC = tabbedPaneOriginal.getComponentAt((tabbedPaneOriginal.getSelectedIndex() + 1) % (tabbedPaneOriginal.getTabCount()));
-                tabbedPaneOriginal.setComponentAt((tabbedPaneOriginal.getSelectedIndex() + 1) % (tabbedPaneOriginal.getTabCount()), null);
-                tabbedPaneSplit.setComponentAt((tabbedPaneOriginal.getSelectedIndex() + 1) % (tabbedPaneOriginal.getTabCount()), tempC);
-                tabbedPaneSplit.setSelectedIndex((tabbedPaneOriginal.getSelectedIndex() + 1) % (tabbedPaneOriginal.getTabCount()));
-                contentPane.updateUI();
-            }
-        });
-
-        tabbedPaneSplit.addChangeListener(changeEvent -> {
-            if (tabbedPaneSplit.getSelectedComponent() == null && !initSplit) {
-                Component tempC = tabbedPaneOriginal.getComponentAt(tabbedPaneSplit.getSelectedIndex());
-                tabbedPaneOriginal.setComponentAt(tabbedPaneSplit.getSelectedIndex(), null);
-                tabbedPaneSplit.setComponentAt(tabbedPaneSplit.getSelectedIndex(), tempC);
-
-                for (int i = 0; i < tabbedPaneOriginal.getTabCount(); i++) {
-                    if (tabbedPaneSplit.getComponentAt(i) != null && tabbedPaneSplit.getComponentAt(i) != tempC) {
-                        tempC = tabbedPaneSplit.getComponentAt(i);
-                        tabbedPaneSplit.setComponentAt(i, null);
-                        tabbedPaneOriginal.setComponentAt(i, tempC);
-                        break;
-                    }
-                }
-                if (tabbedPaneOriginal.getSelectedIndex() == tabbedPaneSplit.getSelectedIndex()) {
-                    tabbedPaneOriginal.setSelectedIndex((tabbedPaneSplit.getSelectedIndex() + 1) % tabbedPaneOriginal.getTabCount());
-                }
-                contentPane.updateUI();
-            }
-        });
-
-        mnNewMenuOptions.add(mnLanguage);
-        canvas.setBackground(Color.WHITE);
-        canvas.setPreferredSize(new Dimension(model.getCanvasX(), model.getCanvasY()));
-        holonCanvas.setBackground(Color.WHITE);
-        holonCanvas.setPreferredSize(new Dimension(model.getCanvasX(), model.getCanvasY()));
-
-        /********************
-         * RIGHT CONTAINER (INFORMATION)
-         **********************/
-        // Set up of the HolonElements section
-        // Two different Models: Multi for multi-selection mode and Single for
-        // single-selection mode (CPS-Object)
-        model.getMultiTable().setColumnIdentifiers(columnNamesMulti);
-        model.getSingleTable().setColumnIdentifiers(columnNamesSingle);
-        model.getTableHolonElement().setBorder(null);
-        model.getTableHolonElement().setFillsViewportHeight(true);
-        model.getTableHolonElement().setCellSelectionEnabled(true);
-        model.getTableHolonElement().setColumnSelectionAllowed(true);
-        tableHolonElementScrollPane.setViewportView(model.getTableHolonElement());
-        scrollElements.setLayout(new BorderLayout(0, 0));
-        scrollElements.add(panelHolonEl, BorderLayout.NORTH);
-        scrollElements.add(tableHolonElementScrollPane);
-        panelHolonEl.setLayout(new BoxLayout(panelHolonEl, BoxLayout.X_AXIS));
-        toolBarHolonEl.add(btnAddHolEL);
-        toolBarHolonEl.add(btnDelHolEL);
-        toolBarHolonEl.setFloatable(false);
-        panelHolonEl.add(toolBarHolonEl);
-
-        // Set up of the Properties section
-        tableProperties.setModel(model.getPropertyTable());
-        tableProperties.setFillsViewportHeight(true);
-        tableProperties.setCellSelectionEnabled(true);
-        tableProperties.setColumnSelectionAllowed(true);
-        scrollProperties.setViewportView(tableProperties);
-
-        // Set up of the Graph section
-        tableGraph.setModel(tableModelGraph);
-        tableGraph.setFillsViewportHeight(true);
-        tableGraph.setCellSelectionEnabled(true);
-        tableGraph.setColumnSelectionAllowed(true);
-        scrollGraph.setViewportView(unitGraph);
-        graphLabel.setLayout(new BorderLayout(0, 10));
-        graphLabel.add(maxGraph, BorderLayout.NORTH);
-        graphLabel.add(medGraph, BorderLayout.CENTER);
-        graphLabel.add(minGraph, BorderLayout.SOUTH);
-
-        toolBarGraph.add(lblSelectedElement);
-        toolBarGraph.add(elementGraph);
-        Component horizontalStrut = Box.createHorizontalStrut(toolBarGraph.getWidth() - resetGraphBtn.getWidth());
-
-        toolBarGraph.add(horizontalStrut);
-        resetGraphBtn.setHorizontalAlignment(SwingConstants.RIGHT);
-
-        toolBarGraph.add(resetGraphBtn);
-        toolBarGraph.setFloatable(false);
-        scrollGraph.setRowHeaderView(graphLabel);
-        scrollGraph.setColumnHeaderView(toolBarGraph);
-
-        tables.add(model.getSingleTable());
-        tables.add(model.getMultiTable());
-        /***********************
-         * HolonElement Table Actions
-         **********************/
-        /*
-         * Add HolonElement to given HolonObject
+	private final AlgorithmMenu algorithmMenu;
+	private final JMenuBar menuBar = new JMenuBar();
+	private final JMenu mnNewMenu = new JMenu("File");
+	private final JMenu mnNewMenuEdit = new JMenu("Edit");
+	private final JMenu mnNewMenuOptions = new JMenu("Options");
+	private final JMenu mnNewMenuView = new JMenu("View");
+	private final JMenu mnHelp = new JMenu("Help");
+	private final JCheckBox consoleLogCheckBox = new JCheckBox(
+			"Show program console log");
+	private final JCheckBox useFlexibleDevicesCheckBox = new JCheckBox(
+			"Automatically use flexible devices");
+	/** checked if supplyBars should be shown */
+	private final JCheckBox showSupplyBarsCheckBox = new JCheckBox(
+			"Show supply bars.");
+	/** menu for the different fairness Models */
+	private final JMenu mnFairnessModel = new JMenu("Fairness Model");
+	/** press to supply minimum demand first */
+	private final JMenuItem mntmFairMinFirst = new JMenuItem(
+			"Minimum demand first");
+	/** press to give everyone the same energy */
+	private final JMenuItem mntmFairAlleEqual = new JMenuItem(
+			"Equal supply for everyone");
+	private final JMenuItem mntmOpen = new JMenuItem("Open");
+	private final JMenuItem mntmNew = new JMenuItem("New");
+	private final JMenuItem mntmSave = new JMenuItem("Save");
+	private final JMenuItem mntmAboutUs = new JMenuItem("About Us");
+	private final JMenuItem mntmCanvasSize = new JMenuItem("View Size");
+	private final JMenuItem mntmBackground = new JMenuItem("Background Image");
+	private final JMenuItem mntmSplitView = new JMenuItem("Split View");
+	private final JSplitPane splitPane = new JSplitPane();
+	private final JSplitPane splitPane1 = new JSplitPane();
+	private final JSplitPane splitPaneCanvasConsole = new JSplitPane(
+			JSplitPane.VERTICAL_SPLIT);
+	// the tabbed canvas containing the different sub-net tabs of the grid (Main
+	// Grid + Nodes of Nodes)
+	private final JTabbedPane tabbedPaneInnerOriginal = new JTabbedPane(
+			JTabbedPane.TOP);
+	// the main canvas where we can see the grid currently displayed
+	private final JScrollPane canvasSP = new JScrollPane();
+	private final JScrollPane scrollPane1 = new JScrollPane();
+	// private final JScrollPane holonSP = new JScrollPane();
+	// the original tabbed Pane (containing tabs for view, statistics, holon,
+	// flexibility)
+	private final JTabbedPane tabbedPaneOriginal = new JTabbedPane(
+			JTabbedPane.TOP);
+	// the same tabbed Pane that appears once the view is split
+	private final JTabbedPane tabbedPaneSplit = new JTabbedPane(JTabbedPane.TOP);
+	private final JPopupMenu popmenuEdit = new JPopupMenu();
+	private final JMenuItem editItem = new JMenuItem("Edit Object");
+	private final StatisticPanel statSplitPane;
+	private final JScrollPane statScrollPane;
+	private final JLabel maxGraph = new JLabel("100%");
+	private final JLabel medGraph = new JLabel("50%");
+	private final JLabel minGraph = new JLabel("0%");
+	private final JLabel elementGraph = new JLabel("None ");
+	private final ArrayList<HolonElement> selectedElements = new ArrayList<>();
+	private final JTree tree = new JTree();
+	/******************************************
+	 ************* Right Container*************
+	 ******************************************
+	 * Right Container: here comes the information about the HolonObject, such
+	 * as HolonElements Information, Properties and Consumption/Production
+	 * graph.
+	 **/
+	private final JSplitPane splitHolonElPro = new JSplitPane(
+			JSplitPane.VERTICAL_SPLIT);
+	private final JSplitPane splitGraphHolonEl = new JSplitPane(
+			JSplitPane.VERTICAL_SPLIT);
+	private final int distanceBetweenElementsAndGraph = 350;
+	// Model for single or multi selection
+	private final JPanel scrollElements = new JPanel();
+	private final JScrollPane tableHolonElementScrollPane = new JScrollPane();
+	// In this section are all the properties that correspond to the clicked
+	// HolonObject, such as connections, name, Type, etc.
+	// Table for Properties --> Cell with (0,1) is editable by CpsObjt and
+	// Cell(3,1) is editable by Edges
+	private final JTable tableProperties = new JTable() {
+
+		private static final long serialVersionUID = 1L;
+
+		@Override
+		public TableCellRenderer getCellRenderer(int row, int column) {
+			if (getValueAt(row, column) instanceof Boolean) {
+				return super.getDefaultRenderer(Boolean.class);
+			} else {
+				return super.getCellRenderer(row, column);
+			}
+		}
+
+		@Override
+		public TableCellEditor getCellEditor(int row, int column) {
+			if (getValueAt(row, column) instanceof Boolean) {
+				return super.getDefaultEditor(Boolean.class);
+			} else {
+				return super.getCellEditor(row, column);
+			}
+		}
+	};
+	private final JPanel graphLabel = new JPanel();
+	private final JScrollPane scrollProperties = new JScrollPane();
+	// In this section is the graph for the selected HolonElement of the clicked
+	// HolonObject
+	private final JTable tableGraph = new JTable();
+	private final DefaultTableModel tableModelGraph = new DefaultTableModel();
+	private final JScrollPane scrollGraph = new JScrollPane();
+	private final Model model;
+	private final Control controller;
+
+	// In this section are all the Holonelements that correspond to the clicked
+	// HolonObject with consumption/production, name and amount.
+	private final JPanel panel = new JPanel();
+	private final JPanel panelHolonEl = new JPanel();
+	private final JComboBox comboBox = new JComboBox();
+	// Buttons
+	private final JButton btnAdd = new JButton("+");
+	private final JButton btnDel = new JButton("-");
+	private final JButton btnAddHolEL = new JButton("+");
+	private final JButton btnDelHolEL = new JButton("-");
+	private final JButton resetGraphBtn = new JButton("Reset");
+	private final JToolBar toolBar = new JToolBar();
+	private final JToolBar toolBarHolonEl = new JToolBar();
+	private final JToolBar toolBarGraph = new JToolBar();
+	// Languages
+	private final JMenuItem englishBtn = new JMenuItem("EN");
+	private final JMenuItem spanishBtn = new JMenuItem("ES");
+	private final JMenuItem germanBtn = new JMenuItem("DE");
+	private final JMenuItem czechBtn = new JMenuItem("CZ");
+	private final JMenuItem chineseBtn = new JMenuItem("ZH");
+	// private final JComboBox comboBoxGraph = new JComboBox();
+	private final Console console = new Console();
+	private final MyCanvas canvas;
+	private final HolonCanvas holonCanvas;
+	private final UnitGraph unitGraph;
+	private final JSplitPane splitPane3 = new JSplitPane();
+	private final JSlider sizeSlider = new JSlider();
+	private final JLabel lblImageSize = new JLabel(Languages.getLanguage()[94]);
+	private final JMenuItem mntmUndo = new JMenuItem("Undo");
+	private final JMenuItem mntmRedo = new JMenuItem("Redo");
+	private final JMenuItem mntmEditEdges = new JMenuItem("Edge Properties");
+	private final JMenuItem mntmFindReplace = new JMenuItem("Find/ Replace");
+	private final JMenuItem mntmEditShowedInformation = new JMenuItem(
+			"Edit showed Information");
+	private final JMenuItem mntmResetCategory = new JMenuItem(
+			"Reset Categories");
+	private final JMenu mnLanguage = new JMenu("Language");
+	private final String[] columnNamesMulti = { "Object", "Nr.", "Device",
+			"Energy", "Flexible Energy Available", "Quantity", "Activated",
+			"Flexible" };
+	private final String[] columnNamesSingle = { "Nr.", "Device", "Energy",
+			"Flexible Energy Available", "Quantity", "Activated", "Flexible" };
+	private final ArrayList<PropertyTable> tables = new ArrayList<>();
+	private final String[] comboBoxCat = { "Category", "Object", "Switch" };
+	private final UpdateController updCon;
+	private final JSplitPane splitPane_1 = new JSplitPane();
+	private final JSlider holonBodySizeSlider = new JSlider();
+	private final JLabel lblHolonBodySize = new JLabel("HolonBody SIze");
+	private final JLabel lblSelectedElement = new JLabel("Selected Element: ");
+	// for doubleclick
+	private boolean click = false;
+	private JFrame frmCyberPhysical;
+	private JTabbedPane tabTemp; // tabbedPaneOriginal or tabbedPaneSplit
+	private JSplitPane tempSplit;
+	private boolean initSplit = true;
+	private String catOfObjToBeEdited;
+	private UpperNodeCanvas unc;
+	private JPanel contentPane;
+	private String holonEleNamesDisplayed = "None ";
+	// Pop up Windows
+	private AddObjectPopUp addObjectPopUP;
+	private AboutUsPopUp aboutUsPopUp;
+	private AddElementPopUp addElementPopUp;
+	// variables
+	private boolean dragging = false;
+	private String actualObjectClicked;
+	private Image img = null;
+	private AbstractCpsObject tempCps = null;
+	private int yValueElements = 0;
+	// Time Stuff
+	private TimePanel timePanel;
+	// Coord for all Cells with text
+	private int yThis;
+	private int xThis;
+	// Coord for all Cells with boolean values (checkbox)
+	private int yBTis;
+	private int xBThis;
+	// Coord for the Edit-Modus in the PropertieTable
+	private int yProThis;
+	private int xProThis;
+	private int yProThisOneClick;
+	private int xProThisOneClick;
+	private AbstractCpsObject temp = null;
+	private String warningText = "Warning";
+	private String saveBeforeNew = "Do you want to save your current data?";
+	private String eraseCategory = "Do you really want to delete the Category ";
+	private String selectObjBeforeErase = "Please select a Category or an Object in order to delete something.";
+
+	/**
+	 * Create the application.
+	 *
+	 * @param control
+	 *            the Controller
+	 */
+	GUI(Control control) {
+		this.controller = control;
+		this.model = control.getModel();
+		statSplitPane = new StatisticPanel(controller);
+		model.addGraphListener(statSplitPane);
+		model.setStatPanel(statSplitPane);
+		statScrollPane = new JScrollPane(statSplitPane);
+		this.unitGraph = new UnitGraph(model, control);
+		this.canvas = new MyCanvas(model, control, unitGraph);
+		this.holonCanvas = new HolonCanvas(model, control);
+
+		control.initListener(this);
+		controller.setCanvas(canvas);
+		model.setConsole(console);
+		algorithmMenu = new AlgorithmMenu(model, control, this);
+		initialize();
+		updateCategories(model.getCategories());
+		updCon = new UpdateController(model, controller);
+	}
+
+	// /**
+	// * Adds a Popup.
+	// *
+	// * @param component Component
+	// * @param popup PopupMenu
+	// */
+	// private static void addPopup(Component component, final JPopupMenu popup)
+	// {
+	// component.addMouseListener(new MouseAdapter() {
+	// public void mousePressed(MouseEvent e) {
+	// if (e.isPopupTrigger()) {
+	// showMenu(e);
+	// }
+	// }
+	//
+	// public void mouseReleased(MouseEvent e) {
+	// if (e.isPopupTrigger()) {
+	// showMenu(e);
+	// }
+	// }
+	//
+	// private void showMenu(MouseEvent e) {
+	// popup.show(e.getComponent(), e.getX(), e.getY());
+	// }
+	//
+	// });
+	// }
+
+	/**
+	 * Initialize the contents of the frame.
+	 */
+	@SuppressWarnings({ "serial", "unchecked" })
+	private void initialize() {
+		frmCyberPhysical = new JFrame();
+		frmCyberPhysical.setTitle("Cyber Physical Systems Model");
+		// try to restore old position/dimensions
+		ArrayList<Integer> savedWindowDim = controller
+				.loadSavedWindowDimensionsIfExistent();
+		if (savedWindowDim.size() == 4) {
+			frmCyberPhysical.setBounds(savedWindowDim.get(0),
+					savedWindowDim.get(1), savedWindowDim.get(2),
+					savedWindowDim.get(3));
+		}
+
+		// if the upper part of the window is showing, the windows can still be
+		// moved,
+		// but if it is not, we need to move it to somewhere else
+		if (savedWindowDim.size() != 4 || !isUpperPanelInsideBounds()) {
+			frmCyberPhysical.setBounds(100, 100, 1000, 800);
+			frmCyberPhysical.setExtendedState(JFrame.MAXIMIZED_BOTH);
+		}
+		frmCyberPhysical.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
+
+		frmCyberPhysical.addWindowListener(new java.awt.event.WindowAdapter() {
+			@Override
+			public void windowClosing(java.awt.event.WindowEvent windowEvent) {
+				if (JOptionPane.showConfirmDialog(frmCyberPhysical,
+						Languages.getLanguage()[88],
+						"Cyber Physical Systems Model",
+						JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE) == JOptionPane.YES_OPTION) {
+					controller.deleteDirectory(new File(System
+							.getProperty("user.home")
+							+ "/.config/HolonGUI/Autosave"));
+
+					// try to save the position and size of the window, such
+					// that (if possible)
+					// it can be opened in the same position the next time
+					try {
+						controller.savePosAndSizeOfWindow(
+								frmCyberPhysical.getX(),
+								frmCyberPhysical.getY(),
+								frmCyberPhysical.getWidth(),
+								frmCyberPhysical.getHeight());
+					} catch (Exception e) {
+						e.printStackTrace();
+					}
+					System.exit(0);
+				}
+			}
+		});
+
+		contentPane = (JPanel) frmCyberPhysical.getContentPane();
+
+		int condition = JComponent.WHEN_IN_FOCUSED_WINDOW;
+		InputMap inputMap = contentPane.getInputMap(condition);
+		ActionMap actionMap = contentPane.getActionMap();
+
+		String cntrlZDown = "controlZ";
+		inputMap.put(KeyStroke.getKeyStroke("control Z"), cntrlZDown);
+		actionMap.put(cntrlZDown, new AbstractAction() {
+
+			private static final long serialVersionUID = 1L;
+
+			@Override
+			public void actionPerformed(ActionEvent e) {
+				try {
+					controller.loadAutoSave(controller.getUndoSave());
+					canvas.repaint();
+					unitGraph.update(model.getObjectsOnCanvas());
+					updateUpperNodes();
+				} catch (IOException eex) {
+					eex.printStackTrace();
+				}
+			}
+		});
+
+		String cntrlYDown = "controlY";
+		inputMap.put(KeyStroke.getKeyStroke("control Y"), cntrlYDown);
+		actionMap.put(cntrlYDown, new AbstractAction() {
+
+			private static final long serialVersionUID = 1L;
+
+			@Override
+			public void actionPerformed(ActionEvent e) {
+				try {
+					controller.loadAutoSave(controller.getRedoSave());
+					canvas.repaint();
+					unitGraph.update(model.getObjectsOnCanvas());
+					updateUpperNodes();
+				} catch (IOException ex) {
+					ex.printStackTrace();
+				}
+			}
+		});
+
+		String cntrlADown = "controlA";
+		inputMap.put(KeyStroke.getKeyStroke("control A"), cntrlADown);
+		AbstractAction controlA = new AbstractAction() {
+			private static final long serialVersionUID = 1L;
+
+			@Override
+			public void actionPerformed(ActionEvent e) {
+				chooseTabTemp();
+
+				model.getSelectedCpsObjects().clear();
+
+				// Uppernode Canvas?
+				JScrollPane scrollPane = getScrollPaneFromTabbedPane();
+				Component canvasOrUpperNodeCanvas = scrollPane.getViewport()
+						.getComponent(0);
+
+				if (canvasOrUpperNodeCanvas instanceof UpperNodeCanvas) {
+					UpperNodeCanvas uNC = (UpperNodeCanvas) canvasOrUpperNodeCanvas;
+					for (AbstractCpsObject cps : uNC.upperNode.getNodes()) {
+						controller.addSelectedObject(cps);
+					}
+					uNC.repaint();
+					// or Canvas?
+				} else if (canvasOrUpperNodeCanvas instanceof MyCanvas) {
+					for (AbstractCpsObject cps : model.getObjectsOnCanvas()) {
+						controller.addSelectedObject(cps);
+					}
+					canvas.repaint();
+				}
+				controller.getObjectsInDepth();
+
+			}
+		};
+		actionMap.put(cntrlADown, controlA);
+
+		String delDown = "delete";
+		inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_DELETE, 0, false),
+				delDown);
+		actionMap.put(delDown, new AbstractAction() {
+
+			private static final long serialVersionUID = 1L;
+
+			@Override
+			public void actionPerformed(ActionEvent e) {
+				chooseTabTemp();
+
+				// Uppernode Canvas?
+				JScrollPane scrollPane = getScrollPaneFromTabbedPane();
+				Component canvasOrUpperNodeCanvas = scrollPane.getViewport()
+						.getComponent(0);
+
+				// check whether a producer was deleted (this triggers a
+				// complete re-evaluation of the net)
+				boolean wasProducerDeleted = false;
+
+				if (canvasOrUpperNodeCanvas instanceof UpperNodeCanvas) {
+					UpperNodeCanvas uNC = (UpperNodeCanvas) canvasOrUpperNodeCanvas;
+					for (AbstractCpsObject cps : model.getSelectedCpsObjects()) {
+
+						if (cps instanceof HolonObject
+								&& ((HolonObject) cps).getState() == HolonObject.PRODUCER) {
+							wasProducerDeleted = true;
+						}
+
+						controller.removeTrackingObj(cps);
+						if (uNC.upperNode.getNodes().contains(cps)) {
+							controller.delObjUpperNode(cps, uNC.upperNode);
+							unc.setToolTip(false);
+
+							// remove UpperNodeTab if UpperNode deleted
+							removeUpperNodeTab(cps);
+						}
+					}
+					uNC.repaint();
+
+					// or Canvas?
+				} else if (canvasOrUpperNodeCanvas instanceof MyCanvas) {
+					boolean save = false;
+					CpsEdge edgeHighlight = model.getSelectedEdge();
+					if (edgeHighlight != null) {
+						controller.removeEdgesOnCanvas(edgeHighlight);
+						((MyCanvas) canvasOrUpperNodeCanvas).edgeHighlight = null;
+					}
+					for (int j = 0; j < model.getSelectedCpsObjects().size(); j++) {
+						AbstractCpsObject cps = model.getSelectedCpsObjects()
+								.get(j);
+
+						if (cps instanceof HolonObject
+								&& ((HolonObject) cps).getState() == HolonObject.PRODUCER) {
+							wasProducerDeleted = true;
+						}
+
+						controller.removeTrackingObj(cps);
+						if (j < model.getSelectedCpsObjects().size() - 1)
+							save = true;
+						controller.delCanvasObject(cps, save);
+						canvas.setToolTip(false);
+
+						// remove UpperNodeTab if UpperNode deleted
+						removeUpperNodeTab(cps);
+					}
+					canvas.repaint();
+				}
+
+				// recalculate net if a producer was deleted
+				if (wasProducerDeleted) {
+					controller.resetSimulation();
+					controller.calculateStateForCurrentTimeStep();
+				}
+
+				model.getSelectedCpsObjects().clear();
+				hideScrollGraph();
+			}
+		});
+
+		String cntrlFDown = "controlF";
+		inputMap.put(KeyStroke.getKeyStroke("control F"), cntrlFDown);
+		actionMap.put(cntrlFDown, new AbstractAction() {
+
+			private static final long serialVersionUID = 1L;
+
+			@Override
+			public void actionPerformed(ActionEvent e) {
+				SearchPopUp dialog = new SearchPopUp(controller, canvas,
+						frmCyberPhysical);
+				dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
+				dialog.setVisible(true);
+			}
+		});
+
+		String cntrlCDown = "controlC";
+		inputMap.put(KeyStroke.getKeyStroke("control C"), cntrlCDown);
+		AbstractAction controlC = new AbstractAction() {
+			private static final long serialVersionUID = 1L;
+
+			@Override
+			public void actionPerformed(ActionEvent e) {
+				chooseTabTemp();
+
+				JScrollPane scrollPane = getScrollPaneFromTabbedPane();
+				if (!model.getSelectedCpsObjects().isEmpty()) {
+					if (scrollPane.getViewport().getComponent(0) instanceof UpperNodeCanvas)
+						controller.copy(((UpperNodeCanvas) scrollPane
+								.getViewport().getComponent(0)).upperNode);
+					else
+						controller.copy(null);
+					if (!model.getClipboradObjects().isEmpty()) {
+						canvas.itemPaste.setEnabled(true);
+					}
+				}
+			}
+		};
+		actionMap.put(cntrlCDown, controlC);
+
+		String cntrlVDown = "controlV";
+		inputMap.put(KeyStroke.getKeyStroke("control V"), cntrlVDown);
+		AbstractAction controlV = new AbstractAction() {
+			private static final long serialVersionUID = 1L;
+
+			@Override
+			public void actionPerformed(ActionEvent e) {
+				try {
+					tabTemp = null;
+					if (tabbedPaneOriginal.getMousePosition() != null) {
+						tabTemp = tabbedPaneOriginal;
+					} else {
+						if (!initSplit) {
+							tabTemp = tabbedPaneSplit;
+						}
+					}
+
+					JScrollPane scrollPane = getScrollPaneFromTabbedPane();
+					Component canvasOrUpperNodeCanvas = scrollPane
+							.getViewport().getComponent(0);
+
+					if (tabTemp != null
+							&& canvasOrUpperNodeCanvas instanceof UpperNodeCanvas) {
+
+						controller
+								.paste(((UpperNodeCanvas) canvasOrUpperNodeCanvas).upperNode,
+										canvasOrUpperNodeCanvas
+												.getMousePosition());
+						unitGraph.update(model.getSelectedCpsObjects());
+						scrollPane.getViewport().getComponent(0).repaint();
+					} else {
+						controller.paste(null, canvas.getMousePosition());
+						unitGraph.update(model.getSelectedCpsObjects());
+						canvas.repaint();
+					}
+				} catch (HeadlessException | JsonParseException
+						| UnsupportedFlavorException | IOException e1) {
+					JLabel message = new JLabel(
+							"The Clipboard information cannot be pasted into Application.");
+					JOptionPane.showMessageDialog(frmCyberPhysical, message,
+							"", JOptionPane.ERROR_MESSAGE);
+				}
+
+			}
+		};
+		actionMap.put(cntrlVDown, controlV);
+
+		String cntrlXDown = "controlX";
+		inputMap.put(KeyStroke.getKeyStroke("control X"), cntrlXDown);
+		AbstractAction controlX = new AbstractAction() {
+			private static final long serialVersionUID = 1L;
+
+			@Override
+			public void actionPerformed(ActionEvent e) {
+				chooseTabTemp();
+
+				JScrollPane scrollPane = getScrollPaneFromTabbedPane();
+				if (!model.getSelectedCpsObjects().isEmpty()) {
+					if (scrollPane.getViewport().getComponent(0) instanceof UpperNodeCanvas) {
+						controller.cut(((UpperNodeCanvas) scrollPane
+								.getViewport().getComponent(0)).upperNode);
+					} else {
+						controller.cut(null);
+					}
+					if (!model.getClipboradObjects().isEmpty()) {
+						canvas.itemPaste.setEnabled(true);
+					}
+					canvas.repaint();
+				}
+			}
+		};
+		actionMap.put(cntrlXDown, controlX);
+
+		frmCyberPhysical.setJMenuBar(menuBar);
+
+		frmCyberPhysical.setIconImage(Util.loadImage(this,
+				"/Images/Dummy_House.png", 30, 30));
+
+		menuBar.add(mnNewMenu);
+
+		mnNewMenu.add(mntmNew);
+
+		mnNewMenu.add(mntmOpen);
+
+		mnNewMenu.add(mntmSave);
+
+		menuBar.add(mnNewMenuEdit);
+
+		mnNewMenuEdit.add(mntmUndo);
+
+		mnNewMenuEdit.add(mntmRedo);
+
+		mnLanguage.add(englishBtn);
+		englishBtn.setIcon(new ImageIcon(new ImageIcon(
+				"res/Button_Images/FlagEN.png").getImage().getScaledInstance(
+				20, 20, java.awt.Image.SCALE_SMOOTH)));
+		mnLanguage.add(spanishBtn);
+		spanishBtn.setIcon(new ImageIcon(new ImageIcon(
+				"res/Button_Images/FlagES.png").getImage().getScaledInstance(
+				20, 20, java.awt.Image.SCALE_SMOOTH)));
+		mnLanguage.add(germanBtn);
+		germanBtn.setIcon(new ImageIcon(new ImageIcon(
+				"res/Button_Images/FlagDE.png").getImage().getScaledInstance(
+				20, 20, java.awt.Image.SCALE_SMOOTH)));
+		// mnLanguage.add(czechBtn);
+		// czechBtn.setIcon(new ImageIcon(new
+		// ImageIcon("res/Button_Images/FlagCZ.png").getImage().getScaledInstance(20,
+		// 20, java.awt.Image.SCALE_SMOOTH)));
+		mnLanguage.add(chineseBtn);
+		chineseBtn.setIcon(new ImageIcon(new ImageIcon(
+				"res/Button_Images/FlagZH.png").getImage().getScaledInstance(
+				20, 20, java.awt.Image.SCALE_SMOOTH)));
+
+		mntmFindReplace.addActionListener(actionEvent -> {
+			try {
+				SearchPopUp dialog = new SearchPopUp(controller, canvas,
+						frmCyberPhysical);
+				dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
+				dialog.setVisible(true);
+				controller.getObjectsInDepth();
+			} catch (Exception ex) {
+				ex.printStackTrace();
+			}
+		});
+
+		mnNewMenuEdit.add(mntmFindReplace);
+		mntmEditShowedInformation
+				.addActionListener(actionEvent -> {
+					try {
+						DisplayedInformationPopUp dialog = new DisplayedInformationPopUp(
+								canvas, contentPane, controller,
+								frmCyberPhysical);
+						dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
+						dialog.setVisible(true);
+					} catch (Exception ex) {
+						ex.printStackTrace();
+					}
+				});
+
+		mnNewMenuEdit.add(mntmEditShowedInformation);
+		mnNewMenuEdit.add(mntmEditEdges);
+		mntmEditEdges.addActionListener(actionEvent -> {
+			EditEdgesPopUp edgePopUp = new EditEdgesPopUp(frmCyberPhysical);
+			edgePopUp.setCanvas(canvas);
+			edgePopUp.setController(controller);
+			edgePopUp.setVisible(true);
+		});
+
+		menuBar.add(mnNewMenuOptions);
+
+		mnNewMenuOptions.add(mntmResetCategory);
+		mntmResetCategory.addActionListener(actionEvent -> {
+			ArrayList<Category> cat = model.getCategories();
+			try {
+				while (!cat.isEmpty()) {
+					controller.deleteCategory(cat.get(0).getName());
+
+				}
+				controller.resetCategorys();
+			} catch (Exception e2) {
+			}
+
+			tree.repaint();
+		});
+		mnNewMenuOptions.add(consoleLogCheckBox);
+		consoleLogCheckBox.setSelected(true);
+		consoleLogCheckBox.addActionListener(arg0 -> controller
+				.setShowConsoleLog(consoleLogCheckBox.isSelected()));
+
+		mnNewMenuOptions.add(useFlexibleDevicesCheckBox);
+		useFlexibleDevicesCheckBox.setSelected(true);
+		useFlexibleDevicesCheckBox
+				.addActionListener(actionEvent -> model
+						.setUseFlexibleDevices(useFlexibleDevicesCheckBox
+								.isSelected()));
+
+		/**
+		 * Add Fairness Model Option to the option Menu
+		 */
+		mnNewMenuOptions.add(mnFairnessModel);
+
+		mnFairnessModel.add(mntmFairMinFirst);
+		mntmFairMinFirst.setForeground(Color.BLUE);
+		mntmFairMinFirst
+		.setToolTipText("HolonObjects with the smallest mininum Demand will be partially supplied first.\n"
+				+ "After that as many HolonObjects as possible will get fully supplied.");
+		canvas.repaint();
+		mntmFairMinFirst
+				.addActionListener(arg0 -> {
+					controller
+							.setFairnessModel(SimulationManager.fairnessMininumDemandFirst);
+					mntmFairMinFirst.setForeground(Color.BLUE);
+					mntmFairAlleEqual.setForeground(mnFairnessModel.getForeground());
+					controller.calculateStateForCurrentTimeStep();
+				});
+
+		mnFairnessModel.add(mntmFairAlleEqual);
+		mntmFairAlleEqual
+		.setToolTipText("HolonObjects will all get the same amount of energy.");
+		canvas.repaint();
+		mntmFairAlleEqual.addActionListener(arg0 -> {
+			controller.setFairnessModel(SimulationManager.fairnessAllEqual);
+			mntmFairAlleEqual.setForeground(Color.BLUE);
+			mntmFairMinFirst.setForeground(mnFairnessModel.getForeground());
+			controller.calculateStateForCurrentTimeStep();
+		});
+
+		menuBar.add(mnNewMenuView);
+
+		mnNewMenuView.add(mntmCanvasSize);
+		mntmCanvasSize.addActionListener(actionEvent -> {
+			CanvasResizePopUp popUp = new CanvasResizePopUp(model, controller,
+					canvas, tabbedPaneOriginal, tabbedPaneSplit,
+					frmCyberPhysical);
+			popUp.setVisible(true);
+		});
+
+		mnNewMenuView.add(splitPane3);
+
+		sizeSlider.setMinimum(15);
+		sizeSlider.setMaximum(115);
+		sizeSlider
+				.addChangeListener(changeEvent -> {
+					controller.setScale(sizeSlider.getValue());
+
+					JScrollPane scrollPane = getScrollPaneFromTabbedPane();
+
+					if (scrollPane.getViewport().getComponent(0) instanceof UpperNodeCanvas) {
+						scrollPane.getViewport().getComponent(0).repaint();
+					} else {
+						canvas.repaint();
+					}
+					if (!initSplit
+							&& scrollPane.getViewport().getComponent(0) instanceof UpperNodeCanvas) {
+						scrollPane.getViewport().getComponent(0).repaint();
+					} else {
+						canvas.repaint();
+					}
+				});
+
+		mnNewMenuView.add(mntmCanvasSize);
+		mnNewMenuView.add(mntmSplitView);
+
+		/*
+		 * Adds Checkbox to turn supply bars on/off
 		 */
-        btnAddHolEL.addActionListener(actionEvent -> {
-            if (model.getSelectedCpsObjects().size() == 1) {
-                AbstractCpsObject tempCpsObject = updCon.getActualCps();
-                if (tempCpsObject != null && tempCpsObject.getClass() == HolonObject.class
-                        && tempCpsObject.getId() != 0) {
-                    addElementPopUp = new AddElementPopUp(frmCyberPhysical);
-                    addElementPopUp.setActualCps(updCon.getActualCps());
-                    addElementPopUp.setVisible(true);
-                    HolonElement ele = addElementPopUp.getElement();
-                    if (ele != null) {
-                        controller.addElementCanvasObject(tempCpsObject.getId(), ele.getEleName(), ele.getAmount(),
-                                ele.getEnergyPerElement(), ele.getId());
-                    }
-                    controller.calculateStateForTimeStep(model.getCurIteration());
-                    triggerUpdateController(null);
-                    contentPane.updateUI();
-                }
-            }
-        });
-        /*
-         * Delete the chosen HolonElement of the selected HolonObject,
+		mnNewMenuView.add(showSupplyBarsCheckBox);
+		showSupplyBarsCheckBox.setSelected(true);
+		showSupplyBarsCheckBox.addActionListener(arg0 -> {
+			controller.setShowSupplyBars(showSupplyBarsCheckBox.isSelected());
+			canvas.repaint();
+		});
+
+		// Split View
+		mntmSplitView
+				.addActionListener(actionEvent -> {
+					if (splitPaneCanvasConsole.getLeftComponent() instanceof JSplitPane) {
+						initSplit = true;
+						Component tempC = tabbedPaneSplit
+								.getSelectedComponent();
+						tabbedPaneOriginal.setComponentAt(
+								tabbedPaneSplit.getSelectedIndex(), tempC);
+						tabbedPaneSplit.removeAll();
+						splitPaneCanvasConsole
+								.setLeftComponent(tabbedPaneOriginal);
+					} else {
+						for (int i = 0; i < tabbedPaneOriginal.getTabCount(); i++) {
+							// add outer tabs
+							// (inner tabs are added by tabbedPaneSplit
+							// changelistener)
+							tabbedPaneSplit.addTab(
+									tabbedPaneOriginal.getTitleAt(i), null);
+						}
+						if (tabbedPaneOriginal.getSelectedComponent() == statScrollPane) {
+							tabbedPaneOriginal.setComponentAt(0, null);
+							tabbedPaneSplit.setComponentAt(0, canvasSP);
+							tabbedPaneSplit.setSelectedIndex(0);
+						} else {
+							tabbedPaneOriginal.setComponentAt(1, null);
+							tabbedPaneSplit.setComponentAt(1, statScrollPane);
+							tabbedPaneSplit.setSelectedIndex(1);
+						}
+						tempSplit = new JSplitPane();
+						tempSplit.setBorder(null);
+						tempSplit.setRightComponent(tabbedPaneSplit);
+						tempSplit.setLeftComponent(tabbedPaneOriginal);
+						tempSplit.setDividerLocation(tabbedPaneOriginal
+								.getWidth() / 2);
+						tempSplit.setResizeWeight(0.9);
+						splitPaneCanvasConsole.setLeftComponent(tempSplit);
+						initSplit = false;
+					}
+					contentPane.updateUI();
+				});
+		mnNewMenuView.add(mntmBackground);
+
+		mntmBackground
+				.addActionListener(actionEvent -> {
+					tabTemp = tabbedPaneOriginal;
+					JScrollPane scrollPane = getScrollPaneFromTabbedPane();
+
+					if (scrollPane.getViewport().getComponent(0) instanceof MyCanvas) {
+						BackgroundPopUp backgroundDialog = new BackgroundPopUp(
+								model, controller, canvas, null,
+								frmCyberPhysical);
+						backgroundDialog
+								.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
+						backgroundDialog.setVisible(true);
+					} else if (scrollPane.getViewport().getComponent(0) instanceof UpperNodeCanvas) {
+						UpperNodeCanvas uNodeCanvas = (UpperNodeCanvas) (scrollPane
+								.getViewport().getComponent(0));
+						BackgroundPopUp backgroundDialog = new BackgroundPopUp(
+								model, controller, null, uNodeCanvas.upperNode,
+								frmCyberPhysical);
+						backgroundDialog
+								.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
+						backgroundDialog.setVisible(true);
+						uNodeCanvas.repaint();
+					}
+				});
+
+		splitPane3.setRightComponent(sizeSlider);
+
+		splitPane3.setLeftComponent(lblImageSize);
+
+		mnNewMenuView.add(splitPane_1);
+		holonBodySizeSlider.setValue(100);
+		holonBodySizeSlider.setMinimum(1);
+
+		holonBodySizeSlider.addChangeListener(changeEvent -> {
+			controller.setHolonBodyScale(holonBodySizeSlider.getValue());
+			tree.setRowHeight(50);
+			canvas.repaint();
+		});
+
+		splitPane_1.setRightComponent(holonBodySizeSlider);
+
+		splitPane_1.setLeftComponent(lblHolonBodySize);
+
+		menuBar.add(algorithmMenu);
+
+		menuBar.add(mnHelp);
+
+		mnHelp.add(mntmAboutUs);
+
+		tabbedPaneOriginal.addChangeListener(changeEvent -> {
+			if (tabbedPaneOriginal.getSelectedComponent() == null) {
+				Component tempC = tabbedPaneSplit.getSelectedComponent();
+				tabbedPaneSplit.setComponentAt(
+						tabbedPaneOriginal.getSelectedIndex(), null);
+				tabbedPaneOriginal.setComponentAt(
+						tabbedPaneOriginal.getSelectedIndex(), tempC);
+				tempC = tabbedPaneOriginal.getComponentAt((tabbedPaneOriginal
+						.getSelectedIndex() + 1)
+						% (tabbedPaneOriginal.getTabCount()));
+				tabbedPaneOriginal.setComponentAt(
+						(tabbedPaneOriginal.getSelectedIndex() + 1)
+								% (tabbedPaneOriginal.getTabCount()), null);
+				tabbedPaneSplit.setComponentAt(
+						(tabbedPaneOriginal.getSelectedIndex() + 1)
+								% (tabbedPaneOriginal.getTabCount()), tempC);
+				tabbedPaneSplit.setSelectedIndex((tabbedPaneOriginal
+						.getSelectedIndex() + 1)
+						% (tabbedPaneOriginal.getTabCount()));
+				contentPane.updateUI();
+			}
+		});
+
+		tabbedPaneSplit.addChangeListener(changeEvent -> {
+			if (tabbedPaneSplit.getSelectedComponent() == null && !initSplit) {
+				Component tempC = tabbedPaneOriginal
+						.getComponentAt(tabbedPaneSplit.getSelectedIndex());
+				tabbedPaneOriginal.setComponentAt(
+						tabbedPaneSplit.getSelectedIndex(), null);
+				tabbedPaneSplit.setComponentAt(
+						tabbedPaneSplit.getSelectedIndex(), tempC);
+
+				for (int i = 0; i < tabbedPaneOriginal.getTabCount(); i++) {
+					if (tabbedPaneSplit.getComponentAt(i) != null
+							&& tabbedPaneSplit.getComponentAt(i) != tempC) {
+						tempC = tabbedPaneSplit.getComponentAt(i);
+						tabbedPaneSplit.setComponentAt(i, null);
+						tabbedPaneOriginal.setComponentAt(i, tempC);
+						break;
+					}
+				}
+				if (tabbedPaneOriginal.getSelectedIndex() == tabbedPaneSplit
+						.getSelectedIndex()) {
+					tabbedPaneOriginal.setSelectedIndex((tabbedPaneSplit
+							.getSelectedIndex() + 1)
+							% tabbedPaneOriginal.getTabCount());
+				}
+				contentPane.updateUI();
+			}
+		});
+
+		mnNewMenuOptions.add(mnLanguage);
+		canvas.setBackground(Color.WHITE);
+		canvas.setPreferredSize(new Dimension(model.getCanvasX(), model
+				.getCanvasY()));
+		holonCanvas.setBackground(Color.WHITE);
+		holonCanvas.setPreferredSize(new Dimension(model.getCanvasX(), model
+				.getCanvasY()));
+
+		/********************
+		 * RIGHT CONTAINER (INFORMATION)
+		 **********************/
+		// Set up of the HolonElements section
+		// Two different Models: Multi for multi-selection mode and Single for
+		// single-selection mode (CPS-Object)
+		model.getMultiTable().setColumnIdentifiers(columnNamesMulti);
+		model.getSingleTable().setColumnIdentifiers(columnNamesSingle);
+		model.getTableHolonElement().setBorder(null);
+		model.getTableHolonElement().setFillsViewportHeight(true);
+		model.getTableHolonElement().setCellSelectionEnabled(true);
+		model.getTableHolonElement().setColumnSelectionAllowed(true);
+		tableHolonElementScrollPane.setViewportView(model
+				.getTableHolonElement());
+		scrollElements.setLayout(new BorderLayout(0, 0));
+		scrollElements.add(panelHolonEl, BorderLayout.NORTH);
+		scrollElements.add(tableHolonElementScrollPane);
+		panelHolonEl.setLayout(new BoxLayout(panelHolonEl, BoxLayout.X_AXIS));
+		toolBarHolonEl.add(btnAddHolEL);
+		toolBarHolonEl.add(btnDelHolEL);
+		toolBarHolonEl.setFloatable(false);
+		panelHolonEl.add(toolBarHolonEl);
+
+		// Set up of the Properties section
+		tableProperties.setModel(model.getPropertyTable());
+		tableProperties.setFillsViewportHeight(true);
+		tableProperties.setCellSelectionEnabled(true);
+		tableProperties.setColumnSelectionAllowed(true);
+		scrollProperties.setViewportView(tableProperties);
+
+		// Set up of the Graph section
+		tableGraph.setModel(tableModelGraph);
+		tableGraph.setFillsViewportHeight(true);
+		tableGraph.setCellSelectionEnabled(true);
+		tableGraph.setColumnSelectionAllowed(true);
+		scrollGraph.setViewportView(unitGraph);
+		graphLabel.setLayout(new BorderLayout(0, 10));
+		graphLabel.add(maxGraph, BorderLayout.NORTH);
+		graphLabel.add(medGraph, BorderLayout.CENTER);
+		graphLabel.add(minGraph, BorderLayout.SOUTH);
+
+		toolBarGraph.add(lblSelectedElement);
+		toolBarGraph.add(elementGraph);
+		Component horizontalStrut = Box.createHorizontalStrut(toolBarGraph
+				.getWidth() - resetGraphBtn.getWidth());
+
+		toolBarGraph.add(horizontalStrut);
+		resetGraphBtn.setHorizontalAlignment(SwingConstants.RIGHT);
+
+		toolBarGraph.add(resetGraphBtn);
+		toolBarGraph.setFloatable(false);
+		scrollGraph.setRowHeaderView(graphLabel);
+		scrollGraph.setColumnHeaderView(toolBarGraph);
+
+		tables.add(model.getSingleTable());
+		tables.add(model.getMultiTable());
+		/***********************
+		 * HolonElement Table Actions
+		 **********************/
+		/*
+		 * Add HolonElement to given HolonObject
+		 */
+		btnAddHolEL.addActionListener(actionEvent -> {
+			if (model.getSelectedCpsObjects().size() == 1) {
+				AbstractCpsObject tempCpsObject = updCon.getActualCps();
+				if (tempCpsObject != null
+						&& tempCpsObject.getClass() == HolonObject.class
+						&& tempCpsObject.getId() != 0) {
+					addElementPopUp = new AddElementPopUp(frmCyberPhysical);
+					addElementPopUp.setActualCps(updCon.getActualCps());
+					addElementPopUp.setVisible(true);
+					HolonElement ele = addElementPopUp.getElement();
+					if (ele != null) {
+						controller.addElementCanvasObject(
+								tempCpsObject.getId(), ele.getEleName(),
+								ele.getAmount(), ele.getEnergyPerElement(),
+								ele.getId());
+					}
+					controller.calculateStateForTimeStep(model
+							.getCurIteration());
+					triggerUpdateController(null);
+					contentPane.updateUI();
+				}
+			}
+		});
+		/*
+		 * Delete the chosen HolonElement of the selected HolonObject,
 		 * Multi-Selection for CpsObjects as well as for HolonElements possible
 		 */
-        btnDelHolEL.addActionListener(actionEvent -> {
-            // For Single Selection of CpsObject
-            if (model.getSelectedCpsObjects().size() == 1) {
-                if (updCon.getActualCps().getClass() == HolonObject.class) {
-                    HolonObject obj = (HolonObject) updCon.getActualCps();
-                    for (HolonElement e : selectedElements) {
-                        controller.deleteElementCanvas(obj.getId(), e.getId());
-                        controller.calculateStateForTimeStep(model.getCurIteration());
-                        triggerUpdateController(null);
-                        contentPane.updateUI();
-                        // Names displayed in graph are not updated
-                    }
-                    model.getEleToDelete().clear();
-                    selectedElements.clear();
-                }
-                // For MultiSelection of CpsObject
-            } else if (model.getSelectedCpsObjects().size() > 1) {
-                for (Integer i : model.getEleToDelete().keySet()) {
-                    for (HolonElement e : model.getEleToDelete().get(i)) {
-                        controller.deleteElementCanvas(i, e.getId());
-                    }
-                }
-                triggerUpdateController(null);
-                model.getEleToDelete().clear();
-                selectedElements.clear();
-            }
-            triggerUpdateController(null);
-            elementGraph.setText(Languages.getLanguage()[25]);
-            holonEleNamesDisplayed = Languages.getLanguage()[25];
-        });
-        /*
-         * Communication between HolonElement Table and displayed Graph and
+		btnDelHolEL.addActionListener(actionEvent -> {
+			// For Single Selection of CpsObject
+				if (model.getSelectedCpsObjects().size() == 1) {
+					if (updCon.getActualCps().getClass() == HolonObject.class) {
+						HolonObject obj = (HolonObject) updCon.getActualCps();
+						for (HolonElement e : selectedElements) {
+							controller.deleteElementCanvas(obj.getId(),
+									e.getId());
+							controller.calculateStateForTimeStep(model
+									.getCurIteration());
+							triggerUpdateController(null);
+							contentPane.updateUI();
+							// Names displayed in graph are not updated
+			}
+			model.getEleToDelete().clear();
+			selectedElements.clear();
+		}
+		// For MultiSelection of CpsObject
+	} else if (model.getSelectedCpsObjects().size() > 1) {
+		for (Integer i : model.getEleToDelete().keySet()) {
+			for (HolonElement e : model.getEleToDelete().get(i)) {
+				controller.deleteElementCanvas(i, e.getId());
+			}
+		}
+		triggerUpdateController(null);
+		model.getEleToDelete().clear();
+		selectedElements.clear();
+	}
+	triggerUpdateController(null);
+	elementGraph.setText(Languages.getLanguage()[25]);
+	holonEleNamesDisplayed = Languages.getLanguage()[25];
+})		;
+		/*
+		 * Communication between HolonElement Table and displayed Graph and
 		 * Properties, as well as selection of different HolonElements
 		 */
-        model.getTableHolonElement().addMouseListener(new MouseAdapter() {
-            public void mousePressed(MouseEvent e) {
-                HolonObject obj = null;
-                if (model.getSelectedCpsObjects().size() == 1
-                        && model.getSelectedCpsObjects().get(0) instanceof HolonObject) {
-                    obj = (HolonObject) updCon.getActualCps();
-                }
-                yValueElements = e.getY();
-                HolonElement ele;
-                // Search for current clicked HolonElement
-                if (model.getSelectedCpsObjects().size() == 1) {
-                    ele = updCon.getActualHolonElement(obj, yValueElements, 0, tables);
-                } else {
-                    ele = updCon.getActualHolonElement(null, yValueElements, 0, tables);
-                }
-                // Multi-Selection of HolonElements through control button +
-                // mouse click
-                if (ele != null) {
-                    // make energy-consumption graph visible
-                    showScrollGraph();
-
-                    if (e.isControlDown()) {
-                        if (!selectedElements.contains(ele)) {
-                            selectedElements.add(ele);
-                            if (!holonEleNamesDisplayed.equals(Languages.getLanguage()[25])) {
-                                holonEleNamesDisplayed = holonEleNamesDisplayed + "; " + ele.getEleName() + " ";
-                            } else {
-                                holonEleNamesDisplayed = ele.getEleName() + " ";
-                            }
-                            unitGraph.repaintWithNewElement(selectedElements);
-                        }
-                        updCon.getActualHolonElement(null, yValueElements, 2, tables);
-                    }
-                    // if no control-button pressed but a HolonElement chosen
-                    else {
-                        selectedElements.clear();
-                        selectedElements.add(ele);
-                        updCon.getActualHolonElement(null, yValueElements, 1, tables);
-                        holonEleNamesDisplayed = ele.getEleName() + " ";
-                        unitGraph.repaintWithNewElement(selectedElements);
-                    }
-                } else {
-                    elementGraph.setText(Languages.getLanguage()[25]);
-                    hideScrollGraph();
-                }
-                // if any HolonElement is double-clicked --> Edit-Mode started
-                // for selected HolonElement
-                if (e.getClickCount() == 2) {
-                    yThis = e.getY();
-                    xThis = e.getX();
-                }
-                // for single click and empty slot
-                if (e.getClickCount() == 1 && ele == null) {
-                    selectedElements.clear();
-                    holonEleNamesDisplayed = Languages.getLanguage()[25];
-                }
-                elementGraph.setText(holonEleNamesDisplayed);
-                yBTis = e.getY();
-                xBThis = e.getX();
-
-            }
-        });
+		model.getTableHolonElement().addMouseListener(new MouseAdapter() {
+			public void mousePressed(MouseEvent e) {
+				HolonObject obj = null;
+				if (model.getSelectedCpsObjects().size() == 1
+						&& model.getSelectedCpsObjects().get(0) instanceof HolonObject) {
+					obj = (HolonObject) updCon.getActualCps();
+				}
+				yValueElements = e.getY();
+				HolonElement ele;
+				// Search for current clicked HolonElement
+				if (model.getSelectedCpsObjects().size() == 1) {
+					ele = updCon.getActualHolonElement(obj, yValueElements, 0,
+							tables);
+				} else {
+					ele = updCon.getActualHolonElement(null, yValueElements, 0,
+							tables);
+				}
+				// Multi-Selection of HolonElements through control button +
+				// mouse click
+				if (ele != null) {
+					// make energy-consumption graph visible
+					showScrollGraph();
+
+					if (e.isControlDown()) {
+						if (!selectedElements.contains(ele)) {
+							selectedElements.add(ele);
+							if (!holonEleNamesDisplayed.equals(Languages
+									.getLanguage()[25])) {
+								holonEleNamesDisplayed = holonEleNamesDisplayed
+										+ "; " + ele.getEleName() + " ";
+							} else {
+								holonEleNamesDisplayed = ele.getEleName() + " ";
+							}
+							unitGraph.repaintWithNewElement(selectedElements);
+						}
+						updCon.getActualHolonElement(null, yValueElements, 2,
+								tables);
+					}
+					// if no control-button pressed but a HolonElement chosen
+					else {
+						selectedElements.clear();
+						selectedElements.add(ele);
+						updCon.getActualHolonElement(null, yValueElements, 1,
+								tables);
+						holonEleNamesDisplayed = ele.getEleName() + " ";
+						unitGraph.repaintWithNewElement(selectedElements);
+					}
+				} else {
+					elementGraph.setText(Languages.getLanguage()[25]);
+					hideScrollGraph();
+				}
+				// if any HolonElement is double-clicked --> Edit-Mode started
+				// for selected HolonElement
+				if (e.getClickCount() == 2) {
+					yThis = e.getY();
+					xThis = e.getX();
+				}
+				// for single click and empty slot
+				if (e.getClickCount() == 1 && ele == null) {
+					selectedElements.clear();
+					holonEleNamesDisplayed = Languages.getLanguage()[25];
+				}
+				elementGraph.setText(holonEleNamesDisplayed);
+				yBTis = e.getY();
+				xBThis = e.getX();
+
+			}
+		});
 
 		/*
-         * Triggered every time a change is made
+		 * Triggered every time a change is made
 		 */
-        model.getTableHolonElement().addPropertyChangeListener(propertyChangeEvent -> {
-            try {
-                int yMouse = yThis;
-                int yBMouse = yBTis;
-                int selectedValueY = (int) Math.floor(yMouse / 16);
-                int selectedValueBY = (int) Math.floor(yBMouse / 16);
-                // ------------------ multi-selection mode ------------------
-                if (model.getSelectedCpsObjects().size() > 1) {
-                    int selectedValueX = (int) Math.floor(xThis / (model.getTableHolonElement().getWidth() / 8));
-                    int selectedValueBX = (int) Math.floor(xBThis / (model.getTableHolonElement().getWidth() / 8));
-                    if (updCon.getHolonObj(yMouse, model.getMultiTable()) != null) {
-                        // For active column (boolean with a checkbox)
-                        if (selectedValueBX == 6) {
-                            HolonElement eleBTemp = updCon.getActualHolonElement(null, yBMouse, 0, tables);
-                            String newBStuff = model.getMultiTable().getValueAt(selectedValueBY, selectedValueBX)
-                                    .toString();
-                            Boolean bTemp = Boolean.parseBoolean(newBStuff);
-                            eleBTemp.setActive(bTemp);
-                        }
-                        // For activeFlex column (boolean with a checkbox)
-                        else if (selectedValueBX == 7) {
-                            HolonElement eleBTemp = updCon.getActualHolonElement(null, yBMouse, 0, tables);
-                            String newBStuff = model.getMultiTable().getValueAt(selectedValueBY, selectedValueBX)
-                                    .toString();
-                            Boolean bTemp = Boolean.parseBoolean(newBStuff);
-                            eleBTemp.setFlexible(bTemp);
-                        } else {
-                            // Update of HolonElement
-                            HolonElement eleTemp = updCon.getActualHolonElement(null, yMouse, 0, tables);
-                            String newStuff = model.getMultiTable().getValueAt(selectedValueY, selectedValueX)
-                                    .toString();
-                            // Name update
-                            if (selectedValueX == 2) {
-                                eleTemp.setEleName(newStuff);
-                            }
-                            // Energy Update
-                            else if (selectedValueX == 3) {
-                                Float ftemp = Float.parseFloat(newStuff);
-                                eleTemp.setEnergyPerElement(ftemp);
-                            }
-                            // Flexibility
-                            else if (selectedValueX == 4) {
-                                Float ftemp = Float.parseFloat(newStuff);
-                                eleTemp.setFlexibleEnergyAvailable(ftemp);
-                            }
-                            // Amount of Elements update
-                            else if (selectedValueX == 5) {
-                                Integer iTemp = Integer.parseInt(newStuff);
-                                eleTemp.setAmount(iTemp);
-                            }
-                        }
-                    }
-                } // ------------------ single-selection mode ------------------
-                else if (model.getSelectedCpsObjects().size() == 1) {
-                    int selectedValueX = (int) Math.floor(xThis / (model.getTableHolonElement().getWidth() / 7));
-                    int selectedValueBX = (int) Math.floor(xBThis / (model.getTableHolonElement().getWidth() / 7));
-                    if (updCon.getActualCps() != null && updCon.getActualCps().getClass() == HolonObject.class) {
-                        HolonElement eleTemp;
-
-                        // For active column (boolean with a checkbox)
-                        if (selectedValueBX == 5) {
-                            eleTemp = updCon
-                                    .getActualHolonElement((HolonObject) updCon.getActualCps(), yBMouse, 0, tables);
-                            String newBStuff = model.getSingleTable().getValueAt(selectedValueBY, selectedValueBX)
-                                    .toString();
-                            Boolean bTemp = Boolean.parseBoolean(newBStuff);
-                            eleTemp.setActive(bTemp);
-
-                        } // For activeFlex column (boolean with a checkbox)
-                        else if (selectedValueBX == 6) {
-                            eleTemp = updCon
-                                    .getActualHolonElement((HolonObject) updCon.getActualCps(), yBMouse, 0, tables);
-                            String newBStuff = model.getSingleTable().getValueAt(selectedValueBY, selectedValueBX)
-                                    .toString();
-                            Boolean bTemp = Boolean.parseBoolean(newBStuff);
-                            eleTemp.setFlexible(bTemp);
-
-                        } else {
-                            // Update of HolonElement
-                            eleTemp = updCon.getActualHolonElement((HolonObject) updCon.getActualCps(),
-                                    yMouse, 0, tables);
-                            String newStuff = model.getSingleTable().getValueAt(selectedValueY, selectedValueX)
-                                    .toString();
-                            // Name update
-                            if (selectedValueX == 1) {
-                                eleTemp.setEleName(newStuff);
-                            } // Energy Update
-                            else if (selectedValueX == 2) {
-                                Float ftemp = Float.parseFloat(newStuff);
-                                eleTemp.setEnergyPerElement(ftemp);
-                            } // Flexibility
-                            else if (selectedValueX == 3) {
-                                Float ftemp = Float.parseFloat(newStuff);
-                                eleTemp.setFlexibleEnergyAvailable(ftemp);
-
-                                // if this is a flexible device and the flexibly available energy was changed,
-                                // set used energy to 0, so that it can be computed anew
-                                if (eleTemp.isFlexible()) {
-                                    eleTemp.setEnergyPerElement(0);
-                                }
-                            }
-                            // Amount of Elements update
-                            else if (selectedValueX == 4) {
-                                Integer iTemp = Integer.parseInt(newStuff);
-                                eleTemp.setAmount(iTemp);
-                            }
-                        }
-
-                        // set all cells anew, if anything was changed
-                        updateElementTableAfterChange(eleTemp, selectedValueBY);
-                    }
-                }
-                controller.calculateStateForTimeStep(model.getCurIteration());
-                model.getSingleTable().fireTableDataChanged();
-                triggerUpdateController(null);
-                contentPane.updateUI();
-                unitGraph.repaint();
-
-                // trigger update of table after UnitGraph was painted
-                SwingUtilities.invokeLater(() -> {
-                    triggerUpdateController(null);
-                });
-            } catch (Exception e) {
-            }
-        });
-        /***********************
-         * HolonElement Properties Actions
-         **********************/
+		model.getTableHolonElement()
+				.addPropertyChangeListener(propertyChangeEvent -> {
+					try {
+						int yMouse = yThis;
+						int yBMouse = yBTis;
+						int selectedValueY = (int) Math.floor(yMouse / 16);
+						int selectedValueBY = (int) Math.floor(yBMouse / 16);
+						// ------------------ multi-selection mode
+						// ------------------
+						if (model.getSelectedCpsObjects().size() > 1) {
+							int selectedValueX = (int) Math
+									.floor(xThis
+											/ (model.getTableHolonElement()
+													.getWidth() / 8));
+							int selectedValueBX = (int) Math
+									.floor(xBThis
+											/ (model.getTableHolonElement()
+													.getWidth() / 8));
+							if (updCon.getHolonObj(yMouse,
+									model.getMultiTable()) != null) {
+								// For active column (boolean with a checkbox)
+								if (selectedValueBX == 6) {
+									HolonElement eleBTemp = updCon
+											.getActualHolonElement(null,
+													yBMouse, 0, tables);
+									String newBStuff = model
+											.getMultiTable()
+											.getValueAt(selectedValueBY,
+													selectedValueBX).toString();
+									Boolean bTemp = Boolean
+											.parseBoolean(newBStuff);
+									eleBTemp.setActive(bTemp);
+								}
+								// For activeFlex column (boolean with a
+								// checkbox)
+								else if (selectedValueBX == 7) {
+									HolonElement eleBTemp = updCon
+											.getActualHolonElement(null,
+													yBMouse, 0, tables);
+									String newBStuff = model
+											.getMultiTable()
+											.getValueAt(selectedValueBY,
+													selectedValueBX).toString();
+									Boolean bTemp = Boolean
+											.parseBoolean(newBStuff);
+									eleBTemp.setFlexible(bTemp);
+								} else {
+									// Update of HolonElement
+									HolonElement eleTemp = updCon
+											.getActualHolonElement(null,
+													yMouse, 0, tables);
+									String newStuff = model
+											.getMultiTable()
+											.getValueAt(selectedValueY,
+													selectedValueX).toString();
+									// Name update
+									if (selectedValueX == 2) {
+										eleTemp.setEleName(newStuff);
+									}
+									// Energy Update
+									else if (selectedValueX == 3) {
+										Float ftemp = Float
+												.parseFloat(newStuff);
+										eleTemp.setEnergyPerElement(ftemp);
+									}
+									// Flexibility
+									else if (selectedValueX == 4) {
+										Float ftemp = Float
+												.parseFloat(newStuff);
+										eleTemp.setFlexibleEnergyAvailable(ftemp);
+									}
+									// Amount of Elements update
+									else if (selectedValueX == 5) {
+										Integer iTemp = Integer
+												.parseInt(newStuff);
+										eleTemp.setAmount(iTemp);
+									}
+								}
+							}
+						} // ------------------ single-selection mode
+							// ------------------
+						else if (model.getSelectedCpsObjects().size() == 1) {
+							int selectedValueX = (int) Math
+									.floor(xThis
+											/ (model.getTableHolonElement()
+													.getWidth() / 7));
+							int selectedValueBX = (int) Math
+									.floor(xBThis
+											/ (model.getTableHolonElement()
+													.getWidth() / 7));
+							if (updCon.getActualCps() != null
+									&& updCon.getActualCps().getClass() == HolonObject.class) {
+								HolonElement eleTemp;
+
+								// For active column (boolean with a checkbox)
+								if (selectedValueBX == 5) {
+									eleTemp = updCon.getActualHolonElement(
+											(HolonObject) updCon.getActualCps(),
+											yBMouse, 0, tables);
+									String newBStuff = model
+											.getSingleTable()
+											.getValueAt(selectedValueBY,
+													selectedValueBX).toString();
+									Boolean bTemp = Boolean
+											.parseBoolean(newBStuff);
+									eleTemp.setActive(bTemp);
+
+								} // For activeFlex column (boolean with a
+									// checkbox)
+								else if (selectedValueBX == 6) {
+									eleTemp = updCon.getActualHolonElement(
+											(HolonObject) updCon.getActualCps(),
+											yBMouse, 0, tables);
+									String newBStuff = model
+											.getSingleTable()
+											.getValueAt(selectedValueBY,
+													selectedValueBX).toString();
+									Boolean bTemp = Boolean
+											.parseBoolean(newBStuff);
+									eleTemp.setFlexible(bTemp);
+
+								} else {
+									// Update of HolonElement
+									eleTemp = updCon.getActualHolonElement(
+											(HolonObject) updCon.getActualCps(),
+											yMouse, 0, tables);
+									String newStuff = model
+											.getSingleTable()
+											.getValueAt(selectedValueY,
+													selectedValueX).toString();
+									// Name update
+									if (selectedValueX == 1) {
+										eleTemp.setEleName(newStuff);
+									} // Energy Update
+									else if (selectedValueX == 2) {
+										Float ftemp = Float
+												.parseFloat(newStuff);
+										eleTemp.setEnergyPerElement(ftemp);
+									} // Flexibility
+									else if (selectedValueX == 3) {
+										Float ftemp = Float
+												.parseFloat(newStuff);
+										eleTemp.setFlexibleEnergyAvailable(ftemp);
+
+										// if this is a flexible device and the
+										// flexibly available energy was
+										// changed,
+										// set used energy to 0, so that it can
+										// be computed anew
+										if (eleTemp.isFlexible()) {
+											eleTemp.setEnergyPerElement(0);
+										}
+									}
+									// Amount of Elements update
+									else if (selectedValueX == 4) {
+										Integer iTemp = Integer
+												.parseInt(newStuff);
+										eleTemp.setAmount(iTemp);
+									}
+								}
+
+								// set all cells anew, if anything was changed
+								updateElementTableAfterChange(eleTemp,
+										selectedValueBY);
+							}
+						}
+						controller.calculateStateForTimeStep(model
+								.getCurIteration());
+						model.getSingleTable().fireTableDataChanged();
+						triggerUpdateController(null);
+						contentPane.updateUI();
+						unitGraph.repaint();
+
+						// trigger update of table after UnitGraph was painted
+						SwingUtilities.invokeLater(() -> {
+							triggerUpdateController(null);
+						});
+					} catch (Exception e) {
+					}
+				});
+		/***********************
+		 * HolonElement Properties Actions
+		 **********************/
 
 		/*
-         * Update of the mouse coord for Edit-Mode
+		 * Update of the mouse coord for Edit-Mode
 		 */
-        tableProperties.addMouseListener(new MouseAdapter() {
-            public void mousePressed(MouseEvent e) {
-                if (e.getClickCount() == 2) {
-                    yProThis = e.getY();
-                    xProThis = e.getX();
-                }
-                yProThisOneClick = e.getY();
-                xProThisOneClick = e.getX();
-            }
-        });
+		tableProperties.addMouseListener(new MouseAdapter() {
+			public void mousePressed(MouseEvent e) {
+				if (e.getClickCount() == 2) {
+					yProThis = e.getY();
+					xProThis = e.getX();
+				}
+				yProThisOneClick = e.getY();
+				xProThisOneClick = e.getX();
+			}
+		});
 
 		/*
-         * Update any change in the Property table
+		 * Update any change in the Property table
+		 */
+		tableProperties.addPropertyChangeListener(propertyChangeEvent -> {
+			try {
+				Object temp;
+				Object btemp;
+				int selValueY = (int) Math.floor(yProThis / 16);
+				int selValueX = (int) Math.floor(xProThis
+						/ (tableProperties.getWidth() / 2));
+				int selValueYBool = (int) Math.floor(yProThisOneClick / 16);
+				int selValueXBool = (int) Math.floor(xProThisOneClick
+						/ (tableProperties.getWidth() / 2));
+				if (updCon.getActualCps() != null) {
+					temp = model.getPropertyTable().getValueAt(selValueY,
+							selValueX);
+					btemp = model.getPropertyTable().getValueAt(selValueYBool,
+							selValueXBool);
+					// Case: Switch selected
+
+				if (updCon.getActualCps() instanceof HolonSwitch) {
+					if (selValueY == 0 && selValueX != 0) {
+						updCon.getActualCps().setName(temp.toString());
+					}
+					if (selValueYBool == 2) {
+						Boolean bbTemp = Boolean.parseBoolean(btemp.toString());
+						((HolonSwitch) updCon.getActualCps())
+								.setManualMode(bbTemp);
+						if (bbTemp) {
+							model.getPropertyTable()
+									.setCellEditable(3, 1, true);
+						} else {
+							model.getPropertyTable().setCellEditable(3, 1,
+									false);
+						}
+					} else if (selValueYBool == 3) {
+						if (((HolonSwitch) updCon.getActualCps())
+								.getManualMode()) {
+							model.getPropertyTable()
+									.setCellEditable(3, 1, true);
+							Boolean bTemp = Boolean.parseBoolean(btemp
+									.toString());
+							((HolonSwitch) updCon.getActualCps())
+									.setManualState(bTemp);
+						}
+					}
+				} // Case: UpperNode selected
+				else if (updCon.getActualCps() instanceof CpsUpperNode
+						&& selValueX != 0) {
+					// Name edition through double click
+					updCon.getActualCps().setName(temp.toString());
+					// Update of name on the tab in the tab section
+					for (int index = 4; index < tabbedPaneOriginal
+							.getTabCount(); index++) {
+						tabTemp = tabbedPaneOriginal;
+						JScrollPane scrollPane = getScrollPaneFromTabbedPane();
+
+						UpperNodeCanvas unc = ((UpperNodeCanvas) scrollPane
+								.getViewport().getComponent(0));
+
+						if (unc.upperNode.getId() == updCon.getActualCps()
+								.getId()) {
+							tabbedPaneOriginal.setTitleAt(index,
+									unc.upperNode.getName());
+							tabbedPaneOriginal.updateUI();
+							if (!initSplit) {
+								tabbedPaneSplit.setTitleAt(index,
+										unc.upperNode.getName());
+								tabbedPaneSplit.updateUI();
+							}
+						}
+					}
+				} // Case: HolonObject is selected
+				else if (updCon.getActualCps() instanceof HolonObject
+						&& selValueX != 0) {
+					// Name edition through double click
+					updCon.getActualCps().setName(temp.toString());
+				}
+			} // Case: Edge is selected
+			else {
+				temp = model.getPropertyTable()
+						.getValueAt(selValueY, selValueX);
+				btemp = model.getPropertyTable().getValueAt(selValueYBool,
+						selValueXBool);
+				// Edit modus for capacity by double clicking
+				if (selValueY == 2) {
+					Float ftemp;
+					if (Float.parseFloat(temp.toString()) >= 0.0) {
+						ftemp = Float.parseFloat(temp.toString());
+					} else {
+						ftemp = model.getSelectedEdge().getCapacity();
+					}
+					model.getSelectedEdge().setCapacity(ftemp);
+				}
+				// Status edition through a check box
+				if (selValueYBool == 3) {
+					Boolean bbTemp = Boolean.parseBoolean(btemp.toString());
+					model.getSelectedEdge().setWorkingState(bbTemp);
+				}
+			}
+			canvas.repaint();
+		} catch (Exception e) {
+		}
+	})	;
+
+		/***********************
+		 * HolonElement Graph Actions
+		 **********************/
+		/*
+		 * Reset the graph of the selected HolonElement
+		 */
+		resetGraphBtn.setBorder(new LineBorder(Color.BLACK));
+		resetGraphBtn.addActionListener(actionEvent -> unitGraph.reset());
+		/*****************************
+		 * RIGHT CONTAINER DONE
+		 *****************************/
+
+		frmCyberPhysical.getContentPane().setLayout(new BorderLayout(0, 0));
+		/****************
+		 * Tree Stuff
+		 ****************/
+
+		// Override Key Actions
+		inputMap = tree.getInputMap();
+		inputMap.put(KeyStroke.getKeyStroke("control C"), cntrlCDown);
+		inputMap.put(KeyStroke.getKeyStroke("control V"), cntrlVDown);
+		inputMap.put(KeyStroke.getKeyStroke("control X"), cntrlXDown);
+		inputMap.put(KeyStroke.getKeyStroke("control A"), cntrlADown);
+
+		TreeCellRenderer customRenderer = new TreeCellRenderer() {
+			@Override
+			public Component getTreeCellRendererComponent(JTree tree,
+					Object value, boolean selected, boolean expanded,
+					boolean leaf, int row, boolean hasFocus) {
+				JLabel label = new JLabel();
+				Image imgR;
+				if (leaf) {
+					for (Category cat : model.getCategories()) {
+						for (AbstractCpsObject cps : cat.getObjects()) {
+							if (value.toString().compareTo(cps.getObjName()) == 0) {
+								imgR = Util.loadImage(this, cps.getImage(), 50,
+										50);
+								if (imgR != null) {
+									label.setIcon(new ImageIcon(imgR));
+								}
+								label.setText(cps.getName());
+							}
+						}
+					}
+				}
+				tree.setRowHeight(50);
+				if (hasFocus) {
+					label.setForeground(new Color(0, 0, 255));
+					label.setOpaque(true);
+				}
+				if (label.getText().length() == 0) {
+					label.setText(value.toString());
+					if (value.toString().compareTo("Categories") != 0) {
+						label.setIcon(new ImageIcon(Util.loadImage(this,
+								"/Images/folder.png")));
+					}
+				}
+
+				return label;
+
+			}
+		};
+
+		tree.setCellRenderer(customRenderer);
+
+		tree.addMouseListener(new MouseAdapter() {
+			public void mouseReleased(MouseEvent e) {
+				try {
+					if (dragging) {
+						chooseTabTemp();
+
+						JScrollPane scrollPane = getScrollPaneFromTabbedPane();
+						Component canvasOrUpperNodeCanvas = scrollPane
+								.getViewport().getComponent(0);
+
+						if (canvasOrUpperNodeCanvas instanceof UpperNodeCanvas) {
+							UpperNodeCanvas unc = (UpperNodeCanvas) canvasOrUpperNodeCanvas;
+
+							int x = (int) unc.getMousePosition().getX() + 16;
+							int y = (int) unc.getMousePosition().getY() + 16;
+
+							if (x > unc.upperNode.getLeftBorder()) {
+
+								AbstractCpsObject h = null;
+								if (tempCps instanceof HolonObject) {
+									h = new HolonObject(tempCps);
+								}
+								if (tempCps instanceof HolonSwitch) {
+									h = new HolonSwitch(tempCps);
+								}
+								if (tempCps instanceof HolonTransformer) {
+									h = new HolonTransformer(tempCps);
+								}
+
+								h.setPosition(x, y);
+
+								controller.addObjUpperNode(h, unc.upperNode);
+								unc.invalidate();
+								unc.repaint();
+								unc.setXY((int) canvas.getMousePosition()
+										.getX(), (int) canvas
+										.getMousePosition().getY());
+							}
+						} else {
+							int x = (int) canvas.getMousePosition().getX() + 16;
+							int y = (int) canvas.getMousePosition().getY() + 16;
+
+							AbstractCpsObject h = null;
+							if (tempCps instanceof HolonObject) {
+								h = new HolonObject(tempCps);
+							}
+							if (tempCps instanceof HolonSwitch) {
+								h = new HolonSwitch(tempCps);
+							}
+							if (tempCps instanceof HolonTransformer) {
+								h = new HolonTransformer(tempCps);
+							}
+
+							h.setPosition(x, y);
+
+							controller.addObjectCanvas(h);
+							canvas.invalidate();
+							canvas.setXY(
+									(int) canvas.getMousePosition().getX(),
+									(int) canvas.getMousePosition().getY());
+							canvas.repaint();
+						}
+						controller.calculateStateForCurrentTimeStep();
+						contentPane.updateUI();
+						dragging = false;
+					}
+				} catch (Exception eex) {
+				}
+				frmCyberPhysical.setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
+			}
+		});
+
+		popmenuEdit.add(editItem);
+		editItem.setEnabled(false);
+		editItem.addActionListener(actionEvent -> {
+		});
+		tree.addMouseListener(new MouseAdapter() {
+			public void mousePressed(MouseEvent e) {
+				try {
+					actualObjectClicked = tree
+							.getPathForLocation(e.getX(), e.getY())
+							.getLastPathComponent().toString();
+					// if an Object was selected, the porperties are shown in
+					// the table
+					DefaultMutableTreeNode selectedNode = (DefaultMutableTreeNode) tree
+							.getPathForLocation(e.getX(), e.getY())
+							.getLastPathComponent();
+					if (selectedNode.getLevel() == 2) {
+						controller.searchCategoryObject(selectedNode
+								.getParent().toString(), selectedNode
+								.toString());
+						updCon.deleteRows(model.getSingleTable());
+						updCon.deleteRows(model.getMultiTable());
+						// if (selected instanceof HolonObject && selected !=
+						// null) {
+						// selected = (HolonObject) selected;
+						// fillElementTable(((HolonObject)
+						// selected).getElements());
+						// }
+					}
+					if (SwingUtilities.isRightMouseButton(e)) {
+						for (Category cat : model.getCategories()) {
+							for (AbstractCpsObject cps : cat.getObjects()) {
+								if (actualObjectClicked.compareTo(cps
+										.getObjName()) == 0
+										&& !(cps instanceof HolonSwitch)) {
+									editItem.setEnabled(true);
+									popmenuEdit.show(e.getComponent(),
+											e.getX(), e.getY());
+									catOfObjToBeEdited = selectedNode
+											.getParent().toString();
+									tempCps = cps;
+								}
+							}
+						}
+					} else {
+						for (Category cat : model.getCategories()) {
+							for (AbstractCpsObject cps : cat.getObjects()) {
+								if (actualObjectClicked.compareTo(cps
+										.getObjName()) == 0) {
+									File checkPath = new File(cps.getImage());
+									if (checkPath.exists()) {
+										img = new ImageIcon(cps.getImage())
+												.getImage()
+												.getScaledInstance(
+														32,
+														32,
+														java.awt.Image.SCALE_SMOOTH);
+									} else {
+										img = Util.loadImage(this,
+												cps.getImage(), 32, 32);
+									}
+									tempCps = cps;
+									dragging = true;
+									Cursor cursor = Toolkit.getDefaultToolkit()
+											.createCustomCursor(img,
+													new Point(0, 0), "Image");
+									frmCyberPhysical.setCursor(cursor);
+								}
+							}
+						}
+					}
+				} catch (Exception eex) {
+				}
+			}
+		});
+		editItem.addActionListener(actionEvent -> {
+			// Remove the selected Object object
+			addObjectPopUP = new AddObjectPopUp(true, tempCps,
+					catOfObjToBeEdited, frmCyberPhysical);
+			addObjectPopUP.setCategory(catOfObjToBeEdited);
+			addObjectPopUP.setController(controller);
+			addObjectPopUP.setVisible(true);
+		});
+		scrollPane1.setViewportView(tree);
+
+		scrollPane1.setColumnHeaderView(panel);
+		panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
+		toolBar.setAlignmentX(Component.LEFT_ALIGNMENT);
+		toolBar.setFloatable(false);
+
+		panel.add(toolBar);
+		comboBox.setMaximumSize(new Dimension(100, 20));
+		toolBar.add(comboBox);
+		comboBox.setModel(new DefaultComboBoxModel(comboBoxCat));
+		// Add Buttonnew DefaultComboBoxModel(comboBoxCat)
+		btnAdd.addActionListener(actionEvent -> {
+			Object nodeInfo = tree.getLastSelectedPathComponent();
+			String selectedOption = comboBox.getSelectedItem().toString();
+			DefaultMutableTreeNode selectedNode = (DefaultMutableTreeNode) nodeInfo;
+			try {
+
+				switch (selectedOption) {
+
+				case "Category":
+					String catName = JOptionPane.showInputDialog(
+							frmCyberPhysical, Languages.getLanguage()[56]);
+					if (catName.length() != 0) {
+						controller.addCategory(catName);
+					}
+					break;
+				case "Object":
+					if (selectedNode == null) {
+						JOptionPane.showMessageDialog(frmCyberPhysical,
+								Languages.getLanguage()[57] + selectedOption
+										+ ".");
+					}
+					if (selectedNode != null && selectedNode.getLevel() == 1) {
+						AbstractCpsObject tmp = new HolonObject("");
+						addObjectPopUP = new AddObjectPopUp(false, tmp, null,
+								frmCyberPhysical);
+						addObjectPopUP.setVisible(true);
+						addObjectPopUP.setController(controller);
+						addObjectPopUP.setCategory(selectedNode.toString());
+					}
+					break;
+
+				default:
+					addObjectAction(selectedOption, selectedNode);
+					break;
+				}
+			} catch (Exception e) {
+			}
+			tree.repaint();
+		});
+		/**
+		 * Pop up - About Us with some important information about the
+		 * developers, source and programming stuff
 		 */
-        tableProperties.addPropertyChangeListener(propertyChangeEvent -> {
-            try {
-                Object temp;
-                Object btemp;
-                int selValueY = (int) Math.floor(yProThis / 16);
-                int selValueX = (int) Math.floor(xProThis / (tableProperties.getWidth() / 2));
-                int selValueYBool = (int) Math.floor(yProThisOneClick / 16);
-                int selValueXBool = (int) Math.floor(xProThisOneClick / (tableProperties.getWidth() / 2));
-                if (updCon.getActualCps() != null) {
-                    temp = model.getPropertyTable().getValueAt(selValueY, selValueX);
-                    btemp = model.getPropertyTable().getValueAt(selValueYBool, selValueXBool);
-                    // Case: Switch selected
-
-                    if (updCon.getActualCps() instanceof HolonSwitch) {
-                        if (selValueY == 0 && selValueX != 0) {
-                            updCon.getActualCps().setName(temp.toString());
-                        }
-                        if (selValueYBool == 2) {
-                            Boolean bbTemp = Boolean.parseBoolean(btemp.toString());
-                            ((HolonSwitch) updCon.getActualCps()).setManualMode(bbTemp);
-                            if (bbTemp) {
-                                model.getPropertyTable().setCellEditable(3, 1, true);
-                            } else {
-                                model.getPropertyTable().setCellEditable(3, 1, false);
-                            }
-                        } else if (selValueYBool == 3) {
-                            if (((HolonSwitch) updCon.getActualCps()).getManualMode()) {
-                                model.getPropertyTable().setCellEditable(3, 1, true);
-                                Boolean bTemp = Boolean.parseBoolean(btemp.toString());
-                                ((HolonSwitch) updCon.getActualCps()).setManualState(bTemp);
-                            }
-                        }
-                    } // Case: UpperNode selected
-                    else if (updCon.getActualCps() instanceof CpsUpperNode && selValueX != 0) {
-                        // Name edition through double click
-                        updCon.getActualCps().setName(temp.toString());
-                        // Update of name on the tab in the tab section
-                        for (int index = 4; index < tabbedPaneOriginal.getTabCount(); index++) {
-                            tabTemp = tabbedPaneOriginal;
-                            JScrollPane scrollPane = getScrollPaneFromTabbedPane();
-
-                            UpperNodeCanvas unc = ((UpperNodeCanvas) scrollPane.getViewport().getComponent(0));
-
-                            if (unc.upperNode.getId() == updCon.getActualCps().getId()) {
-                                tabbedPaneOriginal.setTitleAt(index, unc.upperNode.getName());
-                                tabbedPaneOriginal.updateUI();
-                                if (!initSplit) {
-                                    tabbedPaneSplit.setTitleAt(index, unc.upperNode.getName());
-                                    tabbedPaneSplit.updateUI();
-                                }
-                            }
-                        }
-                    } // Case: HolonObject is selected
-                    else if (updCon.getActualCps() instanceof HolonObject && selValueX != 0) {
-                        // Name edition through double click
-                        updCon.getActualCps().setName(temp.toString());
-                    }
-                } // Case: Edge is selected
-                else {
-                    temp = model.getPropertyTable().getValueAt(selValueY, selValueX);
-                    btemp = model.getPropertyTable().getValueAt(selValueYBool, selValueXBool);
-                    // Edit modus for capacity by double clicking
-                    if (selValueY == 2) {
-                        Float ftemp;
-                        if (Float.parseFloat(temp.toString()) >= 0.0) {
-                            ftemp = Float.parseFloat(temp.toString());
-                        } else {
-                            ftemp = model.getSelectedEdge().getCapacity();
-                        }
-                        model.getSelectedEdge().setCapacity(ftemp);
-                    }
-                    // Status edition through a check box
-                    if (selValueYBool == 3) {
-                        Boolean bbTemp = Boolean.parseBoolean(btemp.toString());
-                        model.getSelectedEdge().setWorkingState(bbTemp);
-                    }
-                }
-                canvas.repaint();
-            } catch (Exception e) {
-            }
-        });
-
-        /***********************
-         * HolonElement Graph Actions
-         **********************/
-        /*
-         * Reset the graph of the selected HolonElement
+		mntmAboutUs.addMouseListener(new MouseAdapter() {
+			@Override
+			public void mousePressed(MouseEvent e) {
+				aboutUsPopUp = new AboutUsPopUp(frmCyberPhysical);
+				aboutUsPopUp.setVisible(true);
+			}
+		});
+
+		/**
+		 * Update of every interaction between the user and the canvas (only on
+		 * the canvas). Basically the update of all the information concerning
+		 * the clicked HolonObject. For multi-selection, the propertyTable would
+		 * be disabled
 		 */
-        resetGraphBtn.setBorder(new LineBorder(Color.BLACK));
-        resetGraphBtn.addActionListener(actionEvent -> unitGraph.reset());
-        /*****************************
-         * RIGHT CONTAINER DONE
-         *****************************/
-
-        frmCyberPhysical.getContentPane().setLayout(new BorderLayout(0, 0));
-        /****************
-         * Tree Stuff
-         ****************/
-
-        // Override Key Actions
-        inputMap = tree.getInputMap();
-        inputMap.put(KeyStroke.getKeyStroke("control C"), cntrlCDown);
-        inputMap.put(KeyStroke.getKeyStroke("control V"), cntrlVDown);
-        inputMap.put(KeyStroke.getKeyStroke("control X"), cntrlXDown);
-        inputMap.put(KeyStroke.getKeyStroke("control A"), cntrlADown);
-
-        TreeCellRenderer customRenderer = new TreeCellRenderer() {
-            @Override
-            public Component getTreeCellRendererComponent(JTree tree, Object value, boolean selected, boolean expanded,
-                                                          boolean leaf, int row, boolean hasFocus) {
-                JLabel label = new JLabel();
-                Image imgR;
-                if (leaf) {
-                    for (Category cat : model.getCategories()) {
-                        for (AbstractCpsObject cps : cat.getObjects()) {
-                            if (value.toString().compareTo(cps.getObjName()) == 0) {
-                                imgR = Util.loadImage(this,cps.getImage(),50,50);
-                                if (imgR != null) {
-                                    label.setIcon(new ImageIcon(imgR));
-                                }
-                                label.setText(cps.getName());
-                            }
-                        }
-                    }
-                }
-                tree.setRowHeight(50);
-                if (hasFocus) {
-                    label.setForeground(new Color(0, 0, 255));
-                    label.setOpaque(true);
-                }
-                if (label.getText().length() == 0) {
-                    label.setText(value.toString());
-                    if (value.toString().compareTo("Categories") != 0) {
-                    	label.setIcon(new ImageIcon(Util.loadImage(this, "/Images/folder.png")));
-                    }
-                }
-
-                return label;
-
-            }
-        };
-
-        tree.setCellRenderer(customRenderer);
-
-        tree.addMouseListener(new MouseAdapter() {
-            public void mouseReleased(MouseEvent e) {
-                try {
-                    if (dragging) {
-                        chooseTabTemp();
-
-                        JScrollPane scrollPane = getScrollPaneFromTabbedPane();
-                        Component canvasOrUpperNodeCanvas = scrollPane.getViewport().getComponent(0);
-
-                        if (canvasOrUpperNodeCanvas instanceof UpperNodeCanvas) {
-                            UpperNodeCanvas unc = (UpperNodeCanvas) canvasOrUpperNodeCanvas;
-
-                            int x = (int) unc.getMousePosition().getX() + 16;
-                            int y = (int) unc.getMousePosition().getY() + 16;
-
-                            if (x > unc.upperNode.getLeftBorder()) {
-
-                                AbstractCpsObject h = null;
-                                if (tempCps instanceof HolonObject) {
-                                    h = new HolonObject(tempCps);
-                                }
-                                if (tempCps instanceof HolonSwitch) {
-                                    h = new HolonSwitch(tempCps);
-                                }
-                                if (tempCps instanceof HolonTransformer) {
-                                    h = new HolonTransformer(tempCps);
-                                }
-
-                                h.setPosition(x, y);
-
-                                controller.addObjUpperNode(h, unc.upperNode);
-                                unc.invalidate();
-                                unc.repaint();
-                                unc.setXY((int) canvas.getMousePosition().getX(),
-                                        (int) canvas.getMousePosition().getY());
-                            }
-                        } else {
-                            int x = (int) canvas.getMousePosition().getX() + 16;
-                            int y = (int) canvas.getMousePosition().getY() + 16;
-
-                            AbstractCpsObject h = null;
-                            if (tempCps instanceof HolonObject) {
-                                h = new HolonObject(tempCps);
-                            }
-                            if (tempCps instanceof HolonSwitch) {
-                                h = new HolonSwitch(tempCps);
-                            }
-                            if (tempCps instanceof HolonTransformer) {
-                                h = new HolonTransformer(tempCps);
-                            }
-
-                            h.setPosition(x, y);
-
-                            controller.addObjectCanvas(h);
-                            canvas.invalidate();
-                            canvas.setXY((int) canvas.getMousePosition().getX(),
-                                    (int) canvas.getMousePosition().getY());
-                            canvas.repaint();
-                        }
-                        controller.calculateStateForCurrentTimeStep();
-                        contentPane.updateUI();
-                        dragging = false;
-                    }
-                } catch (Exception eex) {
-                }
-                frmCyberPhysical.setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
-            }
-        });
-
-        popmenuEdit.add(editItem);
-        editItem.setEnabled(false);
-        editItem.addActionListener(actionEvent -> {
-        });
-        tree.addMouseListener(new MouseAdapter() {
-            public void mousePressed(MouseEvent e) {
-                try {
-                    actualObjectClicked = tree.getPathForLocation(e.getX(), e.getY()).getLastPathComponent().toString();
-                    // if an Object was selected, the porperties are shown in
-                    // the table
-                    DefaultMutableTreeNode selectedNode = (DefaultMutableTreeNode) tree
-                            .getPathForLocation(e.getX(), e.getY()).getLastPathComponent();
-                    if (selectedNode.getLevel() == 2) {
-                        controller.searchCategoryObject(selectedNode.getParent().toString(), selectedNode.toString());
-                        updCon.deleteRows(model.getSingleTable());
-                        updCon.deleteRows(model.getMultiTable());
-                        // if (selected instanceof HolonObject && selected !=
-                        // null) {
-                        // selected = (HolonObject) selected;
-                        // fillElementTable(((HolonObject)
-                        // selected).getElements());
-                        // }
-                    }
-                    if (SwingUtilities.isRightMouseButton(e)) {
-                        for (Category cat : model.getCategories()) {
-                            for (AbstractCpsObject cps : cat.getObjects()) {
-                                if (actualObjectClicked.compareTo(cps.getObjName()) == 0
-                                        && !(cps instanceof HolonSwitch)) {
-                                    editItem.setEnabled(true);
-                                    popmenuEdit.show(e.getComponent(), e.getX(), e.getY());
-                                    catOfObjToBeEdited = selectedNode.getParent().toString();
-                                    tempCps = cps;
-                                }
-                            }
-                        }
-                    } else {
-                        for (Category cat : model.getCategories()) {
-                            for (AbstractCpsObject cps : cat.getObjects()) {
-                                if (actualObjectClicked.compareTo(cps.getObjName()) == 0) {
-                                    File checkPath = new File(cps.getImage());
-                                    if (checkPath.exists()) {
-                                        img = new ImageIcon(cps.getImage()).getImage().getScaledInstance(32, 32,
-                                                java.awt.Image.SCALE_SMOOTH);
-                                    } else {
-                                    	img = Util.loadImage(this,cps.getImage(),32,32);
-                                    }
-                                    tempCps = cps;
-                                    dragging = true;
-                                    Cursor cursor = Toolkit.getDefaultToolkit().createCustomCursor(img, new Point(0, 0),
-                                            "Image");
-                                    frmCyberPhysical.setCursor(cursor);
-                                }
-                            }
-                        }
-                    }
-                } catch (Exception eex) {
-                }
-            }
-        });
-        editItem.addActionListener(actionEvent -> {
-            // Remove the selected Object object
-            addObjectPopUP = new AddObjectPopUp(true, tempCps, catOfObjToBeEdited, frmCyberPhysical);
-            addObjectPopUP.setCategory(catOfObjToBeEdited);
-            addObjectPopUP.setController(controller);
-            addObjectPopUP.setVisible(true);
-        });
-        scrollPane1.setViewportView(tree);
-
-        scrollPane1.setColumnHeaderView(panel);
-        panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
-        toolBar.setAlignmentX(Component.LEFT_ALIGNMENT);
-        toolBar.setFloatable(false);
-
-        panel.add(toolBar);
-        comboBox.setMaximumSize(new Dimension(100, 20));
-        toolBar.add(comboBox);
-        comboBox.setModel(new DefaultComboBoxModel(comboBoxCat));
-        // Add Buttonnew DefaultComboBoxModel(comboBoxCat)
-        btnAdd.addActionListener(actionEvent -> {
-            Object nodeInfo = tree.getLastSelectedPathComponent();
-            String selectedOption = comboBox.getSelectedItem().toString();
-            DefaultMutableTreeNode selectedNode = (DefaultMutableTreeNode) nodeInfo;
-            try {
-
-                switch (selectedOption) {
-
-                    case "Category":
-                        String catName = JOptionPane.showInputDialog(frmCyberPhysical, Languages.getLanguage()[56]);
-                        if (catName.length() != 0) {
-                            controller.addCategory(catName);
-                        }
-                        break;
-                    case "Object":
-                        if (selectedNode == null) {
-                            JOptionPane.showMessageDialog(frmCyberPhysical,
-                                    Languages.getLanguage()[57] + selectedOption + ".");
-                        }
-                        if (selectedNode != null && selectedNode.getLevel() == 1) {
-                            AbstractCpsObject tmp = new HolonObject("");
-                            addObjectPopUP = new AddObjectPopUp(false, tmp, null, frmCyberPhysical);
-                            addObjectPopUP.setVisible(true);
-                            addObjectPopUP.setController(controller);
-                            addObjectPopUP.setCategory(selectedNode.toString());
-                        }
-                        break;
-
-                    default:
-                        addObjectAction(selectedOption, selectedNode);
-                        break;
-                }
-            } catch (Exception e) {
-            }
-            tree.repaint();
-        });
-        /**
-         * Pop up - About Us with some important information about the
-         * developers, source and programming stuff
-         */
-        mntmAboutUs.addMouseListener(new MouseAdapter() {
-            @Override
-            public void mousePressed(MouseEvent e) {
-                aboutUsPopUp = new AboutUsPopUp(frmCyberPhysical);
-                aboutUsPopUp.setVisible(true);
-            }
-        });
-
-        /**
-         * Update of every interaction between the user and the canvas (only on
-         * the canvas). Basically the update of all the information concerning
-         * the clicked HolonObject. For multi-selection, the propertyTable would
-         * be disabled
-         */
-        canvas.addMouseListener(new MouseAdapter() {
-            @Override
-            public void mousePressed(MouseEvent e) {
-
-            }
-
-            @Override
-            public void mouseReleased(MouseEvent e) {
-                holonEleNamesDisplayed = Languages.getLanguage()[25];
-                // If any empty space is clicked
-                if (temp == null || temp.getId() != model.getSelectedObjectID()) {
-                    hideScrollGraph();
-                    elementGraph.setText(Languages.getLanguage()[25]);
-                }
-                temp = updCon.getActualCps();
-                // Erase old data in the PropertyTable
-                if (model.getPropertyTable().getRowCount() > 0) {
-                    for (int i = model.getPropertyTable().getRowCount() - 1; i > -1; i--) {
-                        model.getPropertyTable().removeRow(i);
-                    }
-                }
-                if (e.isControlDown() && temp != null) {
-                    if (model.getSelectedCpsObjects().contains(temp)) {
-                        controller.deleteSelectedObject(temp);
-                    } else {
-                        controller.addSelectedObject(temp);
-                    }
-                }
-                if (temp instanceof HolonSwitch) {
-                    showScrollGraph();
-                    unitGraph.repaintWithNewSwitch((HolonSwitch) temp);
-                    unitGraph.fillArrayofBooleans();
-                }
-                // Write new data in the PropertyTable
-                triggerUpdateController(temp);
-
-                // New Tab with NodeOfNode
-                if (doubleClick() && MouseEvent.BUTTON3 != e.getButton() && temp instanceof CpsUpperNode) {
-                    openNewUpperNodeTab();
-                    try {
-                        controller.autoSave();
-                    } catch (IOException e1) {
-                        e1.printStackTrace();
-                    }
-                }
-                if (model.getSelectedCpsObjects().size() > 1) {
-                    model.getTableHolonElement().setModel(model.getMultiTable());
-                } else if (model.getSelectedCpsObjects().size() == 1) {
-                    model.getTableHolonElement().setModel(model.getSingleTable());
-                }
-
-            }
-
-        });
-
-        holonCanvas.addMouseListener(new MouseAdapter() {
-            @Override
-            public void mousePressed(MouseEvent e) {
-                hideScrollGraph();
-                elementGraph.setText(Languages.getLanguage()[25]);
-                if (model.getPropertyTable().getRowCount() > 0) {
-                    for (int i = model.getPropertyTable().getRowCount() - 1; i > -1; i--) {
-                        model.getPropertyTable().removeRow(i);
-                    }
-                }
-                updCon.deleteRows(model.getMultiTable());
-                updCon.deleteRows(model.getSingleTable());
-                updCon.paintHolonBody(model.getSelectedHolonBody());
-            }
-        });
-
-        toolBar.add(btnAdd);
-
-        // Del Button
-        btnDel.addActionListener(actionEvent -> {
-            Object nodeInfo = tree.getLastSelectedPathComponent();
-            if (nodeInfo != null) {
-                DefaultMutableTreeNode selectedNode = (DefaultMutableTreeNode) nodeInfo;
-                String nodeName = selectedNode.getUserObject().toString();
-                int depthOfNode = selectedNode.getLevel();
-                try {
-                    switch (depthOfNode) {
-                        case 1:
-                            int dialogResult = JOptionPane.showConfirmDialog(frmCyberPhysical, eraseCategory + nodeName + "?",
-                                    warningText, JOptionPane.YES_NO_OPTION);
-                            if (dialogResult == JOptionPane.YES_OPTION) {
-                                controller.deleteCategory(nodeName);
-                            }
-                            break;
-                        case 2:
-                            DefaultMutableTreeNode parent = (DefaultMutableTreeNode) selectedNode.getParent();
-                            controller.delObjectCategory(parent.getUserObject().toString(), nodeName);
-                            break;
-
-                        default:
-                            JOptionPane.showMessageDialog(frmCyberPhysical, selectObjBeforeErase);
-                    }
-                } catch (Exception e2) {
-                }
-
-            } else {
-                JOptionPane.showMessageDialog(frmCyberPhysical, selectObjBeforeErase);
-            }
-            tree.repaint();
-        });
-        toolBar.add(btnDel);
-
-        frmCyberPhysical.getContentPane().add(splitPane);
-
-        mntmNew.addActionListener(actionEvent -> {
-            if (model.getObjectsOnCanvas().size() != 0) {
-                int newWarning = JOptionPane.YES_NO_OPTION;
-                int dialogForNewWarning = JOptionPane.showConfirmDialog(frmCyberPhysical, saveBeforeNew, warningText,
-                        newWarning);
-                if (dialogForNewWarning == JOptionPane.YES_OPTION) {
-                    mntmSave.doClick();
-                }
-            }
-
-            model.getEdgesOnCanvas().removeAll(model.getEdgesOnCanvas());
-            model.getObjectsOnCanvas().removeAll(model.getObjectsOnCanvas());
-            controller.setSelectedObjectID(0);
-            controller.setSelecteEdge(null);
-            controller.setCurIteration(0);
-            hideScrollGraph();
-            elementGraph.setText(Languages.getLanguage()[25]);
-            canvas.tempCps = null;
-            canvas.repaint();
-            IdCounter.resetCounter();
-            IdCounterElem.resetCounter();
-        });
-
-        mntmOpen.addActionListener(new ActionListener() {
-            @Override
-            public void actionPerformed(ActionEvent evt) {
-                menuFileExitActionPerformed();
-            }
-
-            private void menuFileExitActionPerformed() {
-                JFileChooser fileChooser = new JFileChooser();
-                FileNameExtensionFilter holonFilter = new FileNameExtensionFilter("Holon Save File(*.holon)", "holon");
-                fileChooser.setFileFilter(holonFilter);
-
-                if (fileChooser.showOpenDialog(frmCyberPhysical) == JFileChooser.APPROVE_OPTION) {
-                    File file = fileChooser.getSelectedFile();
-
-                    try {
-                        controller.loadFile(file.getAbsolutePath());
-                        canvas.repaint();
-                        unitGraph.update(model.getObjectsOnCanvas());
-                        tree.repaint();
-                        for (JsonObject json : model.getStatisticData()) {
-                            readStatistics(json);
-                        }
-                    } catch (IOException | ArchiveException e) {
-                        e.printStackTrace();
-                        JLabel message = new JLabel("The savefile is corrupt and cannot be opened.");
-                        JOptionPane.showMessageDialog(frmCyberPhysical, message, "", JOptionPane.ERROR_MESSAGE);
-                    }
-                }
-            }
-        });
-
-        mntmSave.addActionListener(new ActionListener() {
-            @Override
-            public void actionPerformed(ActionEvent evt) {
-                menuSaveActionPerformed();
-            }
-
-            private void menuSaveActionPerformed() {
-                JFileChooser fileChooser = new JFileChooser();
-                FileNameExtensionFilter holonFilter = new FileNameExtensionFilter("Holon Save File(*.holon)", "holon");
-                fileChooser.setFileFilter(holonFilter);
-
-                if (fileChooser.showSaveDialog(frmCyberPhysical) == JFileChooser.APPROVE_OPTION) {
-                    String file = fileChooser.getSelectedFile().getPath();
-                    if (fileChooser.getFileFilter().equals(holonFilter)) {
-                        if (!file.contains("."))
-                            file += ".holon";
-                    }
-                    if (!file.endsWith(".holon")) {
-                        String suffix = file.substring(file.lastIndexOf("."), file.length());
-                        String[] options = new String[]{"keep .holon", "use " + suffix};
-
-                        JLabel message = new JLabel(
-                                "Are you sure to use the extension \"" + suffix + "\" instead of \".holon\"?");
-
-                        int response = JOptionPane.showOptionDialog(frmCyberPhysical, message, "", JOptionPane.DEFAULT_OPTION,
-                                JOptionPane.QUESTION_MESSAGE, null, options, options[1]);
-
-                        if (response == 0)
-                            file = file.replace(suffix, ".holon");
-                    }
-
-                    try {
-                        controller.saveFile(new File(file).getAbsolutePath());
-                    } catch (IOException | ArchiveException e) {
-                        e.printStackTrace();
-                    }
-                }
-            }
-        });
-
-        englishBtn.addActionListener(actionEvent -> {
-            Languages.setLanguage(0);
-            refreshLanguages();
-            updCon.refreshTableProperties(model.getPropertyTable());
-        });
-        spanishBtn.addActionListener(actionEvent -> {
-            Languages.setLanguage(1);
-            refreshLanguages();
-            updCon.refreshTableProperties(model.getPropertyTable());
-        });
-        germanBtn.addActionListener(actionEvent -> {
-            Languages.setLanguage(2);
-            refreshLanguages();
-            updCon.refreshTableProperties(model.getPropertyTable());
-        });
-        czechBtn.addActionListener(actionEvent -> {
-            Languages.setLanguage(3);
-            refreshLanguages();
-            updCon.refreshTableProperties(model.getPropertyTable());
-        });
-        chineseBtn.addActionListener(actionEvent -> {
-            Languages.setLanguage(4);
-            refreshLanguages();
-            updCon.refreshTableProperties(model.getPropertyTable());
-        });
-
-        mntmUndo.addActionListener(new ActionListener() {
-            @Override
-            public void actionPerformed(ActionEvent evt) {
-                menuUndoActionPerformed();
-            }
-
-            private void menuUndoActionPerformed() {
-                try {
-                    controller.loadAutoSave(controller.getUndoSave());
-                    canvas.repaint();
-
-                    repaintGraphAfterUndoRedo();
-                    hideScrollGraph();
-                } catch (IOException e) {
-                    e.printStackTrace();
-                }
-            }
-        });
-
-        mntmRedo.addActionListener(new ActionListener() {
-            @Override
-            public void actionPerformed(ActionEvent evt) {
-                menuRedoActionPerformed();
-            }
-
-            private void menuRedoActionPerformed() {
-                try {
-                    controller.loadAutoSave(controller.getRedoSave());
-                    canvas.repaint();
-
-                    repaintGraphAfterUndoRedo();
-                    hideScrollGraph();
-                } catch (IOException e) {
-                    e.printStackTrace();
-                }
-            }
-        });
-
-        timePanel = new TimePanel(model, controller);
-        timePanel.setBorder(null);
-        ((JSlider) (timePanel.getComponent(1))).addChangeListener(changeEvent -> {
-            int i = model.getCurIteration();
-            controller.calculateStateForTimeStep(i);
-            unitGraph.repaint();
-            if (model.getIsSimRunning()) {
-                controller.runAlgorithm(model, controller);
-                statSplitPane.repaintGraphs();
-            }
-            contentPane.updateUI();
-        });
-        splitPane1.setMinimumSize(new Dimension(0, 25));
-        splitPane.setRightComponent(splitPane1);
-        splitPane.setDividerLocation(200);
-        splitPane1.setDividerLocation(500);
-        splitPaneCanvasConsole.setDividerLocation(550);
-        splitPaneCanvasConsole.setResizeWeight(0.9);
-
-        splitPane.setLeftComponent(scrollPane1);
-        splitPaneCanvasConsole.setLeftComponent(tabbedPaneOriginal);
-        tabbedPaneOriginal.addTab("View", tabbedPaneInnerOriginal);
-        tabbedPaneInnerOriginal.addTab("Main Grid", canvasSP);
-        tabbedPaneOriginal.addTab("Statistics", statScrollPane);
-        tabbedPaneOriginal.addTab("Holon", holonCanvas);
-        FlexiblePane flexPane = new FlexiblePane(controller);
-        controller.setFlexiblePane(flexPane);
-        controller.getModel().getObjectListeners().add(flexPane);
-        tabbedPaneOriginal.addTab("Flexibility", flexPane);
-
-        splitPaneCanvasConsole.setRightComponent(console);
-        splitPane1.setLeftComponent(splitPaneCanvasConsole);
-        splitPane1.setRightComponent(splitHolonElPro);
-
-        splitPane1.setResizeWeight(0.9);
-
-        splitHolonElPro.setDividerLocation(700);
-        // containing the graph and the elements-list
-        splitHolonElPro.setTopComponent(splitGraphHolonEl);
-        // containing the object's properties
-        splitHolonElPro.setBottomComponent(scrollProperties);
-
-        splitGraphHolonEl.setDividerLocation(distanceBetweenElementsAndGraph);
-        splitGraphHolonEl.setTopComponent(scrollElements);
-        splitGraphHolonEl.setBottomComponent(scrollGraph);
-        canvasSP.setViewportView(canvas);
-        algorithmMenu.setBackground(new Color(240, 240, 240));
-
-        tabbedPaneOriginal.setBorder(null);
-        scrollProperties.setBorder(null);
-        scrollGraph.setBorder(null);
-        scrollElements.setBorder(null);
-        splitPane.setBorder(null);
-        splitPane1.setBorder(null);
-        splitPaneCanvasConsole.setBorder(null);
-        splitHolonElPro.setBorder(null);
-        splitGraphHolonEl.setBorder(null);
-        panelHolonEl.setBorder(null);
-        canvasSP.setBorder(null);
-
-        tableHolonElementScrollPane.setBorder(null);
-
-        frmCyberPhysical.getContentPane().add(timePanel, BorderLayout.SOUTH);
-
-        MouseAdapter focusCanvasAdapter = new FocusCanvasMouseAdapter();
-        model.getTableHolonElement().addMouseListener(focusCanvasAdapter);
-        tableProperties.addMouseListener(focusCanvasAdapter);
-        console.getConsoleText().addMouseListener(focusCanvasAdapter);
-
-        try {
-            controller.loadAutoSave(System.getProperty("user.home") + "/.config/HolonGUI/Category/Category.json");
-        } catch (IOException e1) {
-        }
-
-        String autoPath = System.getProperty("user.home") + "/.config/HolonGUI/Autosave/";
-        File dest = new File(autoPath);
-        ArrayList<File> oldAutoSaves = controller.filterOldAutoSaveFiles();
-        int nrOfOldSaves = oldAutoSaves.size();
-
-        if (nrOfOldSaves > 0) {
-            int dialogButton = JOptionPane.YES_NO_OPTION;
-            int dialogResult = JOptionPane.showConfirmDialog(frmCyberPhysical, "Old autosave file was found, should it be loaded?",
-                    warningText, dialogButton);
-            if (dialogResult == JOptionPane.YES_OPTION) {
-                if (dest.exists()) {
-                    model.setAutoSaveNr(nrOfOldSaves - 1);
-                    mntmRedo.doClick();
-                } else {
-                    JOptionPane.showMessageDialog(frmCyberPhysical, "Autosave could not be loaded.");
-                    setUpAutoSave(dest);
-                }
-            } else {
-                setUpAutoSave(dest);
-            }
-
-            // after all: delete the obsolete/old autosave files from the directory
-            controller.deleteObsoleteAutoSaveFiles();
-        }
-
-        canvasSP.addComponentListener(new ComponentAdapter() {
-            @Override
-            public void componentResized(ComponentEvent e) {
-                controller.setCanvasX(Math.max(model.getCanvasX(), canvasSP.getViewport().getWidth()));
-                controller.setCanvasY(Math.max(model.getCanvasY(), canvasSP.getViewport().getHeight()));
-                canvas.repaint();
-            }
-        });
-    }
-
-    private void showScrollGraph() {
-        scrollGraph.setVisible(true);
-        splitGraphHolonEl.setBottomComponent(scrollGraph);
-        splitGraphHolonEl.setDividerLocation(distanceBetweenElementsAndGraph);
-    }
-
-    private void hideScrollGraph() {
-        scrollGraph.setVisible(false);
-        unitGraph.empty();
-        splitGraphHolonEl.remove(scrollGraph);
-        splitGraphHolonEl.setDividerLocation(0);
-    }
-
-    private boolean isUpperPanelInsideBounds() {
-        int x = frmCyberPhysical.getX();
-        int y = frmCyberPhysical.getY();
-        int width = frmCyberPhysical.getWidth();
-
-        // get all connected screen devices
-        GraphicsDevice[] screenDevices = GraphicsEnvironment.getLocalGraphicsEnvironment().getScreenDevices();
-        boolean isUpperPanelVisible = false;
-
-        // and check whether they contain the upper left or upper right point of the frame
-        for (GraphicsDevice device : screenDevices) {
-            Rectangle bounds = device.getDefaultConfiguration().getBounds();
-            if (bounds.contains(x, y) || bounds.contains(x + width, y)) {
-                isUpperPanelVisible = true;
-                break;
-            }
-        }
-
-        return isUpperPanelVisible;
-    }
-
-    /**
-     * Sets up autosave if no old one is loaded at the beginning
-     *
-     * @param dest path to save-folder
-     */
-    private void setUpAutoSave(File dest) {
-        dest.mkdirs();
-        try {
-            controller.autoSave();
-        } catch (IOException e1) {
-            e1.printStackTrace();
-        }
-    }
-
-    /**
-     * adds a specific object type to selected Category also handles input
-     * windows and illegal inputs.
-     *
-     * @param objType      type of the Object
-     * @param selectedNode The selected Node
-     */
-    private void addObjectAction(String objType, DefaultMutableTreeNode selectedNode) {
-        if (selectedNode == null) {
-            JOptionPane.showMessageDialog(frmCyberPhysical,
-                    "Please select a Category first before adding " + objType + ".");
-        }
-        // if selected node is a directory for Categories
-        else {
-            if (selectedNode.getLevel() == 1) {
-                String objname = JOptionPane.showInputDialog(frmCyberPhysical, "Please enter a Name for the " + objType);
-                Category cat = controller.searchCategory(selectedNode.getUserObject().toString());
-
-                if (objname.length() != 0) {
-                    try {
-                        switch (objType) {
-
-                            case "Switch":
-                                controller.addSwitch(cat, objname);
-                                break;
-                        }
-                    } catch (Exception e) {
-                    }
-
-                }
-            } else {
-                JOptionPane.showMessageDialog(frmCyberPhysical,
-                        "Objects can not be added to Objects. Please select a Category.");
-            }
-        }
-    }
-
-    /**
-     * reloads the Categories from Model.
-     *
-     * @param categories the current categories
-     */
-    private void updateCategories(final ArrayList<Category> categories) {
-        tree.setModel(new DefaultTreeModel(new DefaultMutableTreeNode("Categories") {
-
-            private static final long serialVersionUID = 1L;
-
-            {
-                DefaultMutableTreeNode node1;
-                for (Category c : categories) {
-                    node1 = new DefaultMutableTreeNode(c.getName());
-
-                    // kann eventuell umgeändert werden
-                    for (AbstractCpsObject obj : c.getObjects()) {
-                        node1.add(new DefaultMutableTreeNode(obj.getObjName()));
-                    }
-                    add(node1);
-                }
-
-            }
-        }));
-    }
-
-    /**
-     * When changes are made to the Categories.
-     *
-     * @param categories the Categories
-     */
-    public void onChange(ArrayList<Category> categories) {
-        DefaultTreeModel model = (DefaultTreeModel) tree.getModel();
-        updateCategories(categories);
-        model.reload();
-    }
-
-    /**
-     * Get the Frame.
-     *
-     * @return the Frame
-     */
-    JFrame getFrmCyberPhysical() {
-        return frmCyberPhysical;
-    }
-
-    private void refreshLanguages() {
-        String[] tempArray = Languages.getLanguage();
-        // ToolBar
-        mnNewMenu.setText(tempArray[0]);
-        mntmNew.setText(tempArray[1]);
-        mntmOpen.setText(tempArray[2]);
-        mntmSave.setText(tempArray[3]);
-        mnNewMenuEdit.setText(tempArray[4]);
-        mntmUndo.setText(tempArray[5]);
-        mntmRedo.setText(tempArray[6]);
-        mntmFindReplace.setText(tempArray[7]);
-        mntmEditShowedInformation.setText(tempArray[8]);
-        mnNewMenuOptions.setText(tempArray[9]);
-        mntmResetCategory.setText(tempArray[10]);
-        mnNewMenuView.setText(tempArray[11]);
-        mntmCanvasSize.setText(tempArray[12]);
-        mnHelp.setText(tempArray[13]);
-        mntmAboutUs.setText(tempArray[14]);
-        mntmEditEdges.setText(tempArray[15]);
-        mnLanguage.setText(tempArray[16]);
-        canvas.updateLanguages();
-
-        // Tables
-        System.arraycopy(tempArray, 17, columnNamesMulti, 0, columnNamesMulti.length);
-        model.getMultiTable().setColumnIdentifiers(columnNamesMulti);
-        System.arraycopy(tempArray, 18, columnNamesSingle, 0, columnNamesSingle.length);
-        model.getSingleTable().setColumnIdentifiers(columnNamesSingle);
-        model.colNames[0] = tempArray[23];
-        model.colNames[1] = tempArray[24];
-        model.getPropertyTable().setColumnIdentifiers(model.colNames);
-        // Graph
-        elementGraph.setText(tempArray[25]);
-        holonEleNamesDisplayed = tempArray[25];
-        resetGraphBtn.setText(tempArray[26]);
-        // Warning PopUps
-        warningText = tempArray[27];
-        saveBeforeNew = tempArray[28];
-        eraseCategory = tempArray[29];
-        selectObjBeforeErase = tempArray[30];
-        // SimMenu
-        algorithmMenu.algoFolderButton.setText(Languages.getLanguage()[85]);
-        // TimePanel
-        timePanel.playBtn.setToolTipText(Languages.getLanguage()[89]);
-        timePanel.timeResetBtn.setToolTipText(Languages.getLanguage()[90]);
-        timePanel.timeForwardBtn.setToolTipText(Languages.getLanguage()[91]);
-        timePanel.timeBackwardBtn.setToolTipText(Languages.getLanguage()[92]);
-        timePanel.timeSlider.setToolTipText(Languages.getLanguage()[93]);
-        // Image Size Slider
-        lblImageSize.setText(Languages.getLanguage()[94]);
-    }
-
-    /**
-     * Checks if a double click was made.
-     *
-     * @return true if doublecklick, false if not
-     */
-    private boolean doubleClick() {
-        if (click) {
-            click = false;
-            return true;
-        } else {
-            click = true;
-            Timer t = new Timer("doubleclickTimer", false);
-            t.schedule(new TimerTask() {
-                @Override
-                public void run() {
-                    click = false;
-                }
-            }, 350);
-        }
-        return false;
-    }
-
-    /*
-     * Open a new Tab with an UpperNodeCanvas
-     */
-    private void openNewUpperNodeTab() {
-        chooseTabTemp();
-
-        JScrollPane scrollPane = getScrollPaneFromTabbedPane();
-        if (scrollPane.getViewport().getComponent(0) instanceof MyCanvas) {
-            unc = new UpperNodeCanvas(model, controller, unitGraph, (CpsUpperNode) temp, "");
-
-        } else {
-            unc = new UpperNodeCanvas(model, controller, unitGraph, (CpsUpperNode) temp,
-                    ((UpperNodeCanvas) scrollPane.getViewport().getComponent(0)).path + " -> ");
-        }
-        unc.setShowedInformation(canvas.getShowedInformation());
-
-        // check if tab already open for clicked NodeOfNode
-        boolean dupl = false;
-
-        for (int i = 1; i < tabbedPaneInnerOriginal.getTabCount(); i++) {
-            JScrollPane paneOriginal = (JScrollPane) tabbedPaneInnerOriginal.getComponentAt(i);
-            if (paneOriginal != null &&
-                    ((UpperNodeCanvas) paneOriginal.getViewport().getComponent(0)).upperNode.getId() == temp.getId()) {
-                dupl = true;
-                // set selected component to view
-                tabbedPaneOriginal.setSelectedComponent(tabbedPaneInnerOriginal);
-                // set selected tab in view to found upper-node-canvas
-                tabbedPaneInnerOriginal.setSelectedComponent(tabbedPaneInnerOriginal.getComponentAt(i));
-            }
-
-            if (tabbedPaneSplit.getTabCount() > 0) {
-                JTabbedPane tabbedPaneInnerSplit = (JTabbedPane) tabbedPaneSplit.getComponentAt(0);
-                if (tabbedPaneInnerSplit != null) {
-                    JScrollPane paneSplit = (JScrollPane) tabbedPaneInnerSplit.getComponentAt(i);
-                    if (!initSplit && paneSplit != null
-                            && ((UpperNodeCanvas) paneSplit.getViewport().getComponent(0)).upperNode.getId() == temp.getId()) {
-                        dupl = true;
-                        // set selected component to view
-                        tabbedPaneSplit.setSelectedComponent(tabbedPaneInnerSplit);
-                        // set selected tab in view to found upper-node-canvas
-                        tabbedPaneInnerSplit.setSelectedComponent(tabbedPaneInnerSplit.getComponentAt(i));
-                    }
-                }
-            }
-
-            // if we found a duplicate, break
-            if (dupl) {
-                break;
-            }
-        }
-        if (!dupl) {
-            unc.setBorder(null);
-            unc.setBackground(Color.WHITE);
-            unc.setPreferredSize(new Dimension(model.getCanvasX(), model.getCanvasY()));
-
-            unc.addMouseListener(new MouseAdapter() {
-                @Override
-                public void mousePressed(MouseEvent e) {
-                    hideScrollGraph();
-                    holonEleNamesDisplayed = Languages.getLanguage()[25];
-                    elementGraph.setText(holonEleNamesDisplayed);
-
-                    chooseTabTemp();
-
-                    JScrollPane scrollPane1 = getScrollPaneFromTabbedPane();
-                    temp = ((UpperNodeCanvas) scrollPane1.getViewport().getComponent(0)).tempCps;
-                    if (doubleClick() && MouseEvent.BUTTON3 != e.getButton() && temp instanceof CpsUpperNode) {
-                        openNewUpperNodeTab();
-                    }
-                    if (temp instanceof HolonSwitch) {
-                        unitGraph.repaintWithNewSwitch((HolonSwitch) temp);
-                        unitGraph.fillArrayofBooleans();
-                    }
-                }
-
-            });
-
-            JScrollPane sp = new JScrollPane(unc);
-            sp.setBorder(null);
-
-            // Selected tabbed Pane = tabbedPaneOriginal or tabbedPaneSplit
-            if (tabTemp == tabbedPaneOriginal) {
-                this.tabbedPaneInnerOriginal.add(temp.getName(), sp);
-                this.tabbedPaneInnerOriginal.setSelectedComponent(sp);
-                this.tabbedPaneInnerOriginal.setTabComponentAt(this.tabbedPaneInnerOriginal.getTabCount() - 1,
-                        new ButtonTabComponent(this.tabbedPaneInnerOriginal, tabbedPaneSplit));
-
-            } else {
-                JTabbedPane tabbedPaneInnerSplit = (JTabbedPane) tabbedPaneSplit.getComponentAt(0);
-                tabbedPaneInnerSplit.add(temp.getName(), sp);
-                Component tempC = tabbedPaneInnerSplit.getSelectedComponent();
-                tabbedPaneInnerSplit.setComponentAt(tabbedPaneInnerSplit.getSelectedIndex(), null);
-                tabbedPaneOriginal.setComponentAt(tabbedPaneInnerSplit.getSelectedIndex(), tempC);
-                tabbedPaneInnerSplit.setSelectedComponent(sp);
-
-                tabbedPaneInnerOriginal.add(temp.getName(), null);
-                tabbedPaneInnerOriginal.setTabComponentAt(tabbedPaneInnerOriginal.getTabCount() - 1,
-                        new ButtonTabComponent(tabbedPaneInnerOriginal, tabbedPaneInnerSplit));
-            }
-
-            temp = null;
-        }
-    }
-
-    private void updateUpperNodes() {
-        for (Component c : tabbedPaneInnerOriginal.getComponents()) {
-            if (!(c instanceof JScrollPane)) {
-                continue;
-            }
-            Component pane = ((JScrollPane) c).getViewport().getComponent(0);
-            if (pane instanceof UpperNodeCanvas) {
-                temp = model.getHashcodeMap().get(((UpperNodeCanvas) pane).code);
-                ((UpperNodeCanvas) pane).upperNode = (CpsUpperNode) temp;
-            }
-        }
-    }
-
-
-    /**
-     * Removes UpperNodeTab if UpperNode was deleted
-     *
-     * @param cps the CPS object that is currently selected
-     */
-    private void removeUpperNodeTab(AbstractCpsObject cps) {
-        if (cps instanceof CpsUpperNode) {
-            boolean splitView = false;
-            for (int i = 1; i < tabbedPaneInnerOriginal.getTabCount(); i++) {
-                JScrollPane scrollPaneOriginal = (JScrollPane) tabbedPaneInnerOriginal.getComponentAt(i);
-
-                if (scrollPaneOriginal == null) {
-                    splitView = true;
-                } else if (((UpperNodeCanvas) scrollPaneOriginal.getViewport().getComponent(0)).upperNode.getId()
-                        == cps.getId()) {
-                    ((ButtonTabComponent) tabbedPaneInnerOriginal.getTabComponentAt(i)).removeTabs();
-                    break;
-                }
-            }
-            // If SplitView is on and the view on
-            // tabbedPaneSplit is the deleted upperNode
-            if (splitView && tabbedPaneSplit.getComponentCount() > 0) {
-                JTabbedPane tabbedPaneInnerSplit = (JTabbedPane) tabbedPaneSplit.getComponentAt(0);
-
-                if (((UpperNodeCanvas) ((JScrollPane) tabbedPaneInnerSplit.getSelectedComponent())
-                        .getViewport().getComponent(0)).upperNode.getId() == cps.getId()) {
-                    ((ButtonTabComponent) tabbedPaneInnerOriginal
-                            .getTabComponentAt(tabbedPaneInnerSplit.getSelectedIndex())).removeTabs();
-                }
-            }
-        }
-    }
-
-    private void readStatistics(JsonObject json) {
-        List<String> keys = json.entrySet().stream().map(i -> i.getKey())
-                .collect(Collectors.toCollection(ArrayList::new));
-
-        // Saved Values
-        JsonObject obj;
-        AbstractCpsObject cps;
-        int prop;
-        Color color;
-
-        StatisticGraphPanel stat = new StatisticGraphPanel(model, controller, json.get("KEY").getAsString(),
-                model.getGraphTable());
-
-        for (String k : keys) {
-            if (!k.equals("KEY")) {
-                obj = json.get(k).getAsJsonObject();
-                cps = (obj.get("ID") == JsonNull.INSTANCE ? null : controller.searchTracked(obj.get("ID").getAsInt()));
-                prop = obj.get("PROPERTY").getAsInt();
-                color = model.getGson().fromJson(obj.get("COLOR"), Color.class);
-                stat.addObject(new TrackedDataSet(cps, prop, color));
-            }
-            model.getGraphTable().put(json.get("KEY").getAsString(), stat);
-            model.getStatPanel().getGraphPanel().add(stat);
-        }
-    }
-
-
-    /**
-     * chooses whether to set the tabTemp to tabbedPaneOriginal or tabbedPaneSplit
-     */
-    private void chooseTabTemp() {
-        // is the uppernode on tabbedPaneOriginal or tabbedPaneSplit
-        if (tabbedPaneOriginal.getMousePosition() != null) {
-            tabTemp = tabbedPaneOriginal;
-        } else {
-            tabTemp = tabbedPaneSplit;
-        }
-    }
-
-    private JScrollPane getScrollPaneFromTabbedPane(JTabbedPane tabbedPane, int index) {
-        tabTemp = tabbedPane;
-        return getScrollPaneFromTabbedPane(index);
-    }
-
-//    private JScrollPane getScrollPaneFromTabbedPane(JTabbedPane tabbedPane) {
-//        return getScrollPaneFromTabbedPane(tabbedPane, -1);
-//    }
-
-    private JScrollPane getScrollPaneFromTabbedPane() {
-        return getScrollPaneFromTabbedPane(-1);
-    }
-
-    private JScrollPane getScrollPaneFromTabbedPane(int index) {
-        Component upperLevelSelectedComponent;
-        if (index == -1) {
-            upperLevelSelectedComponent = tabTemp.getSelectedComponent();
-        } else {
-            upperLevelSelectedComponent = tabTemp.getComponentAt(index);
-        }
-
-        if (upperLevelSelectedComponent instanceof JTabbedPane) {
-            return (JScrollPane) ((JTabbedPane) upperLevelSelectedComponent).getSelectedComponent();
-        } else if (upperLevelSelectedComponent instanceof JScrollPane) {
-            return (JScrollPane) upperLevelSelectedComponent;
-        } else {
-            return null;
-        }
-    }
-
-    private void repaintGraphAfterUndoRedo() {
-        for (AbstractCpsObject cps : model.getObjectsOnCanvas()) {
-            unitGraph.repaintGraph(cps);
-        }
-    }
-
-    /**
-     * if flexibility was turned on, then active needs to be turned off, the energy currently produced/consumed
-     *
-     * @param eleBTemp        element that needs to be updated
-     * @param selectedValueBY the y value in the table
-     */
-    private void updateElementTableAfterChange(HolonElement eleBTemp, int selectedValueBY) {
-        model.getSingleTable().setValueAt(eleBTemp.isFlexible(), selectedValueBY, 6);
-        model.getSingleTable().setValueAt(eleBTemp.isActive(), selectedValueBY, 5);
-        model.getSingleTable().setValueAt(eleBTemp.getAmount(), selectedValueBY, 4);
-        model.getSingleTable().setValueAt(eleBTemp.getFlexibleEnergyAvailablePerElement(), selectedValueBY, 3);
-        model.getSingleTable().setValueAt(eleBTemp.getEnergyPerElement(), selectedValueBY, 2);
-    }
-
-    private void triggerUpdateController(AbstractCpsObject temp) {
-        if (temp != null) {
-            updCon.paintProperties(temp);
-        }
-        updCon.refreshTableHolonElement(model.getMultiTable(), model.getSingleTable());
-        updCon.refreshTableProperties(model.getPropertyTable());
-    }
-
-    /**
-     * Custom Mouse adapter makes contentPane gain focus once mouse leaves this component
-     * so copy/paste/cut and "select all" works
-     */
-    private class FocusCanvasMouseAdapter extends MouseAdapter {
-        @Override
-        public void mouseExited(MouseEvent e) {
-            contentPane.requestFocus();
-        }
-    }
+		canvas.addMouseListener(new MouseAdapter() {
+			@Override
+			public void mousePressed(MouseEvent e) {
+
+			}
+
+			@Override
+			public void mouseReleased(MouseEvent e) {
+				holonEleNamesDisplayed = Languages.getLanguage()[25];
+				// If any empty space is clicked
+				if (temp == null || temp.getId() != model.getSelectedObjectID()) {
+					hideScrollGraph();
+					elementGraph.setText(Languages.getLanguage()[25]);
+				}
+				temp = updCon.getActualCps();
+				// Erase old data in the PropertyTable
+				if (model.getPropertyTable().getRowCount() > 0) {
+					for (int i = model.getPropertyTable().getRowCount() - 1; i > -1; i--) {
+						model.getPropertyTable().removeRow(i);
+					}
+				}
+				if (e.isControlDown() && temp != null) {
+					if (model.getSelectedCpsObjects().contains(temp)) {
+						controller.deleteSelectedObject(temp);
+					} else {
+						controller.addSelectedObject(temp);
+					}
+				}
+				if (temp instanceof HolonSwitch) {
+					showScrollGraph();
+					unitGraph.repaintWithNewSwitch((HolonSwitch) temp);
+					unitGraph.fillArrayofBooleans();
+				}
+				// Write new data in the PropertyTable
+				triggerUpdateController(temp);
+
+				// New Tab with NodeOfNode
+				if (doubleClick() && MouseEvent.BUTTON3 != e.getButton()
+						&& temp instanceof CpsUpperNode) {
+					openNewUpperNodeTab();
+					try {
+						controller.autoSave();
+					} catch (IOException e1) {
+						e1.printStackTrace();
+					}
+				}
+				if (model.getSelectedCpsObjects().size() > 1) {
+					model.getTableHolonElement()
+							.setModel(model.getMultiTable());
+				} else if (model.getSelectedCpsObjects().size() == 1) {
+					model.getTableHolonElement().setModel(
+							model.getSingleTable());
+				}
+
+			}
+
+		});
+
+		holonCanvas.addMouseListener(new MouseAdapter() {
+			@Override
+			public void mousePressed(MouseEvent e) {
+				hideScrollGraph();
+				elementGraph.setText(Languages.getLanguage()[25]);
+				if (model.getPropertyTable().getRowCount() > 0) {
+					for (int i = model.getPropertyTable().getRowCount() - 1; i > -1; i--) {
+						model.getPropertyTable().removeRow(i);
+					}
+				}
+				updCon.deleteRows(model.getMultiTable());
+				updCon.deleteRows(model.getSingleTable());
+				updCon.paintHolonBody(model.getSelectedHolonBody());
+			}
+		});
+
+		toolBar.add(btnAdd);
+
+		// Del Button
+		btnDel.addActionListener(actionEvent -> {
+			Object nodeInfo = tree.getLastSelectedPathComponent();
+			if (nodeInfo != null) {
+				DefaultMutableTreeNode selectedNode = (DefaultMutableTreeNode) nodeInfo;
+				String nodeName = selectedNode.getUserObject().toString();
+				int depthOfNode = selectedNode.getLevel();
+				try {
+					switch (depthOfNode) {
+					case 1:
+						int dialogResult = JOptionPane.showConfirmDialog(
+								frmCyberPhysical, eraseCategory + nodeName
+										+ "?", warningText,
+								JOptionPane.YES_NO_OPTION);
+						if (dialogResult == JOptionPane.YES_OPTION) {
+							controller.deleteCategory(nodeName);
+						}
+						break;
+					case 2:
+						DefaultMutableTreeNode parent = (DefaultMutableTreeNode) selectedNode
+								.getParent();
+						controller.delObjectCategory(parent.getUserObject()
+								.toString(), nodeName);
+						break;
+
+					default:
+						JOptionPane.showMessageDialog(frmCyberPhysical,
+								selectObjBeforeErase);
+					}
+				} catch (Exception e2) {
+				}
+
+			} else {
+				JOptionPane.showMessageDialog(frmCyberPhysical,
+						selectObjBeforeErase);
+			}
+			tree.repaint();
+		});
+		toolBar.add(btnDel);
+
+		frmCyberPhysical.getContentPane().add(splitPane);
+
+		mntmNew.addActionListener(actionEvent -> {
+			if (model.getObjectsOnCanvas().size() != 0) {
+				int newWarning = JOptionPane.YES_NO_OPTION;
+				int dialogForNewWarning = JOptionPane.showConfirmDialog(
+						frmCyberPhysical, saveBeforeNew, warningText,
+						newWarning);
+				if (dialogForNewWarning == JOptionPane.YES_OPTION) {
+					mntmSave.doClick();
+				}
+			}
+
+			model.getEdgesOnCanvas().removeAll(model.getEdgesOnCanvas());
+			model.getObjectsOnCanvas().removeAll(model.getObjectsOnCanvas());
+			controller.setSelectedObjectID(0);
+			controller.setSelecteEdge(null);
+			controller.setCurIteration(0);
+			hideScrollGraph();
+			elementGraph.setText(Languages.getLanguage()[25]);
+			canvas.tempCps = null;
+			canvas.repaint();
+			IdCounter.resetCounter();
+			IdCounterElem.resetCounter();
+		});
+
+		mntmOpen.addActionListener(new ActionListener() {
+			@Override
+			public void actionPerformed(ActionEvent evt) {
+				menuFileExitActionPerformed();
+			}
+
+			private void menuFileExitActionPerformed() {
+				JFileChooser fileChooser = new JFileChooser();
+				FileNameExtensionFilter holonFilter = new FileNameExtensionFilter(
+						"Holon Save File(*.holon)", "holon");
+				fileChooser.setFileFilter(holonFilter);
+
+				if (fileChooser.showOpenDialog(frmCyberPhysical) == JFileChooser.APPROVE_OPTION) {
+					File file = fileChooser.getSelectedFile();
+
+					try {
+						controller.loadFile(file.getAbsolutePath());
+						canvas.repaint();
+						unitGraph.update(model.getObjectsOnCanvas());
+						tree.repaint();
+						for (JsonObject json : model.getStatisticData()) {
+							readStatistics(json);
+						}
+					} catch (IOException | ArchiveException e) {
+						e.printStackTrace();
+						JLabel message = new JLabel(
+								"The savefile is corrupt and cannot be opened.");
+						JOptionPane.showMessageDialog(frmCyberPhysical,
+								message, "", JOptionPane.ERROR_MESSAGE);
+					}
+				}
+			}
+		});
+
+		mntmSave.addActionListener(new ActionListener() {
+			@Override
+			public void actionPerformed(ActionEvent evt) {
+				menuSaveActionPerformed();
+			}
+
+			private void menuSaveActionPerformed() {
+				JFileChooser fileChooser = new JFileChooser();
+				FileNameExtensionFilter holonFilter = new FileNameExtensionFilter(
+						"Holon Save File(*.holon)", "holon");
+				fileChooser.setFileFilter(holonFilter);
+
+				if (fileChooser.showSaveDialog(frmCyberPhysical) == JFileChooser.APPROVE_OPTION) {
+					String file = fileChooser.getSelectedFile().getPath();
+					if (fileChooser.getFileFilter().equals(holonFilter)) {
+						if (!file.contains("."))
+							file += ".holon";
+					}
+					if (!file.endsWith(".holon")) {
+						String suffix = file.substring(file.lastIndexOf("."),
+								file.length());
+						String[] options = new String[] { "keep .holon",
+								"use " + suffix };
+
+						JLabel message = new JLabel(
+								"Are you sure to use the extension \"" + suffix
+										+ "\" instead of \".holon\"?");
+
+						int response = JOptionPane.showOptionDialog(
+								frmCyberPhysical, message, "",
+								JOptionPane.DEFAULT_OPTION,
+								JOptionPane.QUESTION_MESSAGE, null, options,
+								options[1]);
+
+						if (response == 0)
+							file = file.replace(suffix, ".holon");
+					}
+
+					try {
+						controller.saveFile(new File(file).getAbsolutePath());
+					} catch (IOException | ArchiveException e) {
+						e.printStackTrace();
+					}
+				}
+			}
+		});
+
+		englishBtn.addActionListener(actionEvent -> {
+			Languages.setLanguage(0);
+			refreshLanguages();
+			updCon.refreshTableProperties(model.getPropertyTable());
+		});
+		spanishBtn.addActionListener(actionEvent -> {
+			Languages.setLanguage(1);
+			refreshLanguages();
+			updCon.refreshTableProperties(model.getPropertyTable());
+		});
+		germanBtn.addActionListener(actionEvent -> {
+			Languages.setLanguage(2);
+			refreshLanguages();
+			updCon.refreshTableProperties(model.getPropertyTable());
+		});
+		czechBtn.addActionListener(actionEvent -> {
+			Languages.setLanguage(3);
+			refreshLanguages();
+			updCon.refreshTableProperties(model.getPropertyTable());
+		});
+		chineseBtn.addActionListener(actionEvent -> {
+			Languages.setLanguage(4);
+			refreshLanguages();
+			updCon.refreshTableProperties(model.getPropertyTable());
+		});
+
+		mntmUndo.addActionListener(new ActionListener() {
+			@Override
+			public void actionPerformed(ActionEvent evt) {
+				menuUndoActionPerformed();
+			}
+
+			private void menuUndoActionPerformed() {
+				try {
+					controller.loadAutoSave(controller.getUndoSave());
+					canvas.repaint();
+
+					repaintGraphAfterUndoRedo();
+					hideScrollGraph();
+				} catch (IOException e) {
+					e.printStackTrace();
+				}
+			}
+		});
+
+		mntmRedo.addActionListener(new ActionListener() {
+			@Override
+			public void actionPerformed(ActionEvent evt) {
+				menuRedoActionPerformed();
+			}
+
+			private void menuRedoActionPerformed() {
+				try {
+					controller.loadAutoSave(controller.getRedoSave());
+					canvas.repaint();
+
+					repaintGraphAfterUndoRedo();
+					hideScrollGraph();
+				} catch (IOException e) {
+					e.printStackTrace();
+				}
+			}
+		});
+
+		timePanel = new TimePanel(model, controller);
+		timePanel.setBorder(null);
+		((JSlider) (timePanel.getComponent(1)))
+				.addChangeListener(changeEvent -> {
+					int i = model.getCurIteration();
+					controller.calculateStateForTimeStep(i);
+					unitGraph.repaint();
+					if (model.getIsSimRunning()) {
+						controller.runAlgorithm(model, controller);
+						statSplitPane.repaintGraphs();
+					}
+					contentPane.updateUI();
+				});
+		splitPane1.setMinimumSize(new Dimension(0, 25));
+		splitPane.setRightComponent(splitPane1);
+		splitPane.setDividerLocation(200);
+		splitPane1.setDividerLocation(500);
+		splitPaneCanvasConsole.setDividerLocation(550);
+		splitPaneCanvasConsole.setResizeWeight(0.9);
+
+		splitPane.setLeftComponent(scrollPane1);
+		splitPaneCanvasConsole.setLeftComponent(tabbedPaneOriginal);
+		tabbedPaneOriginal.addTab("View", tabbedPaneInnerOriginal);
+		tabbedPaneInnerOriginal.addTab("Main Grid", canvasSP);
+		tabbedPaneOriginal.addTab("Statistics", statScrollPane);
+		tabbedPaneOriginal.addTab("Holon", holonCanvas);
+		FlexiblePane flexPane = new FlexiblePane(controller);
+		controller.setFlexiblePane(flexPane);
+		controller.getModel().getObjectListeners().add(flexPane);
+		tabbedPaneOriginal.addTab("Flexibility", flexPane);
+
+		splitPaneCanvasConsole.setRightComponent(console);
+		splitPane1.setLeftComponent(splitPaneCanvasConsole);
+		splitPane1.setRightComponent(splitHolonElPro);
+
+		splitPane1.setResizeWeight(0.9);
+
+		splitHolonElPro.setDividerLocation(700);
+		// containing the graph and the elements-list
+		splitHolonElPro.setTopComponent(splitGraphHolonEl);
+		// containing the object's properties
+		splitHolonElPro.setBottomComponent(scrollProperties);
+
+		splitGraphHolonEl.setDividerLocation(distanceBetweenElementsAndGraph);
+		splitGraphHolonEl.setTopComponent(scrollElements);
+		splitGraphHolonEl.setBottomComponent(scrollGraph);
+		canvasSP.setViewportView(canvas);
+		algorithmMenu.setBackground(new Color(240, 240, 240));
+
+		tabbedPaneOriginal.setBorder(null);
+		scrollProperties.setBorder(null);
+		scrollGraph.setBorder(null);
+		scrollElements.setBorder(null);
+		splitPane.setBorder(null);
+		splitPane1.setBorder(null);
+		splitPaneCanvasConsole.setBorder(null);
+		splitHolonElPro.setBorder(null);
+		splitGraphHolonEl.setBorder(null);
+		panelHolonEl.setBorder(null);
+		canvasSP.setBorder(null);
+
+		tableHolonElementScrollPane.setBorder(null);
+
+		frmCyberPhysical.getContentPane().add(timePanel, BorderLayout.SOUTH);
+
+		MouseAdapter focusCanvasAdapter = new FocusCanvasMouseAdapter();
+		model.getTableHolonElement().addMouseListener(focusCanvasAdapter);
+		tableProperties.addMouseListener(focusCanvasAdapter);
+		console.getConsoleText().addMouseListener(focusCanvasAdapter);
+
+		try {
+			controller.loadAutoSave(System.getProperty("user.home")
+					+ "/.config/HolonGUI/Category/Category.json");
+		} catch (IOException e1) {
+		}
+
+		String autoPath = System.getProperty("user.home")
+				+ "/.config/HolonGUI/Autosave/";
+		File dest = new File(autoPath);
+		ArrayList<File> oldAutoSaves = controller.filterOldAutoSaveFiles();
+		int nrOfOldSaves = oldAutoSaves.size();
+
+		if (nrOfOldSaves > 0) {
+			int dialogButton = JOptionPane.YES_NO_OPTION;
+			int dialogResult = JOptionPane.showConfirmDialog(frmCyberPhysical,
+					"Old autosave file was found, should it be loaded?",
+					warningText, dialogButton);
+			if (dialogResult == JOptionPane.YES_OPTION) {
+				if (dest.exists()) {
+					model.setAutoSaveNr(nrOfOldSaves - 1);
+					mntmRedo.doClick();
+				} else {
+					JOptionPane.showMessageDialog(frmCyberPhysical,
+							"Autosave could not be loaded.");
+					setUpAutoSave(dest);
+				}
+			} else {
+				setUpAutoSave(dest);
+			}
+
+			// after all: delete the obsolete/old autosave files from the
+			// directory
+			controller.deleteObsoleteAutoSaveFiles();
+		}
+
+		canvasSP.addComponentListener(new ComponentAdapter() {
+			@Override
+			public void componentResized(ComponentEvent e) {
+				controller.setCanvasX(Math.max(model.getCanvasX(), canvasSP
+						.getViewport().getWidth()));
+				controller.setCanvasY(Math.max(model.getCanvasY(), canvasSP
+						.getViewport().getHeight()));
+				canvas.repaint();
+			}
+		});
+	}
+
+	private void showScrollGraph() {
+		scrollGraph.setVisible(true);
+		splitGraphHolonEl.setBottomComponent(scrollGraph);
+		splitGraphHolonEl.setDividerLocation(distanceBetweenElementsAndGraph);
+	}
+
+	private void hideScrollGraph() {
+		scrollGraph.setVisible(false);
+		unitGraph.empty();
+		splitGraphHolonEl.remove(scrollGraph);
+		splitGraphHolonEl.setDividerLocation(0);
+	}
+
+	private boolean isUpperPanelInsideBounds() {
+		int x = frmCyberPhysical.getX();
+		int y = frmCyberPhysical.getY();
+		int width = frmCyberPhysical.getWidth();
+
+		// get all connected screen devices
+		GraphicsDevice[] screenDevices = GraphicsEnvironment
+				.getLocalGraphicsEnvironment().getScreenDevices();
+		boolean isUpperPanelVisible = false;
+
+		// and check whether they contain the upper left or upper right point of
+		// the frame
+		for (GraphicsDevice device : screenDevices) {
+			Rectangle bounds = device.getDefaultConfiguration().getBounds();
+			if (bounds.contains(x, y) || bounds.contains(x + width, y)) {
+				isUpperPanelVisible = true;
+				break;
+			}
+		}
+
+		return isUpperPanelVisible;
+	}
+
+	/**
+	 * Sets up autosave if no old one is loaded at the beginning
+	 *
+	 * @param dest
+	 *            path to save-folder
+	 */
+	private void setUpAutoSave(File dest) {
+		dest.mkdirs();
+		try {
+			controller.autoSave();
+		} catch (IOException e1) {
+			e1.printStackTrace();
+		}
+	}
+
+	/**
+	 * adds a specific object type to selected Category also handles input
+	 * windows and illegal inputs.
+	 *
+	 * @param objType
+	 *            type of the Object
+	 * @param selectedNode
+	 *            The selected Node
+	 */
+	private void addObjectAction(String objType,
+			DefaultMutableTreeNode selectedNode) {
+		if (selectedNode == null) {
+			JOptionPane.showMessageDialog(frmCyberPhysical,
+					"Please select a Category first before adding " + objType
+							+ ".");
+		}
+		// if selected node is a directory for Categories
+		else {
+			if (selectedNode.getLevel() == 1) {
+				String objname = JOptionPane.showInputDialog(frmCyberPhysical,
+						"Please enter a Name for the " + objType);
+				Category cat = controller.searchCategory(selectedNode
+						.getUserObject().toString());
+
+				if (objname.length() != 0) {
+					try {
+						switch (objType) {
+
+						case "Switch":
+							controller.addSwitch(cat, objname);
+							break;
+						}
+					} catch (Exception e) {
+					}
+
+				}
+			} else {
+				JOptionPane
+						.showMessageDialog(frmCyberPhysical,
+								"Objects can not be added to Objects. Please select a Category.");
+			}
+		}
+	}
+
+	/**
+	 * reloads the Categories from Model.
+	 *
+	 * @param categories
+	 *            the current categories
+	 */
+	private void updateCategories(final ArrayList<Category> categories) {
+		tree.setModel(new DefaultTreeModel(new DefaultMutableTreeNode(
+				"Categories") {
+
+			private static final long serialVersionUID = 1L;
+
+			{
+				DefaultMutableTreeNode node1;
+				for (Category c : categories) {
+					node1 = new DefaultMutableTreeNode(c.getName());
+
+					// kann eventuell umgeändert werden
+					for (AbstractCpsObject obj : c.getObjects()) {
+						node1.add(new DefaultMutableTreeNode(obj.getObjName()));
+					}
+					add(node1);
+				}
+
+			}
+		}));
+	}
+
+	/**
+	 * When changes are made to the Categories.
+	 *
+	 * @param categories
+	 *            the Categories
+	 */
+	public void onChange(ArrayList<Category> categories) {
+		DefaultTreeModel model = (DefaultTreeModel) tree.getModel();
+		updateCategories(categories);
+		model.reload();
+	}
+
+	/**
+	 * Get the Frame.
+	 *
+	 * @return the Frame
+	 */
+	JFrame getFrmCyberPhysical() {
+		return frmCyberPhysical;
+	}
+
+	private void refreshLanguages() {
+		String[] tempArray = Languages.getLanguage();
+		// ToolBar
+		mnNewMenu.setText(tempArray[0]);
+		mntmNew.setText(tempArray[1]);
+		mntmOpen.setText(tempArray[2]);
+		mntmSave.setText(tempArray[3]);
+		mnNewMenuEdit.setText(tempArray[4]);
+		mntmUndo.setText(tempArray[5]);
+		mntmRedo.setText(tempArray[6]);
+		mntmFindReplace.setText(tempArray[7]);
+		mntmEditShowedInformation.setText(tempArray[8]);
+		mnNewMenuOptions.setText(tempArray[9]);
+		mntmResetCategory.setText(tempArray[10]);
+		mnNewMenuView.setText(tempArray[11]);
+		mntmCanvasSize.setText(tempArray[12]);
+		mnHelp.setText(tempArray[13]);
+		mntmAboutUs.setText(tempArray[14]);
+		mntmEditEdges.setText(tempArray[15]);
+		mnLanguage.setText(tempArray[16]);
+		canvas.updateLanguages();
+
+		// Tables
+		System.arraycopy(tempArray, 17, columnNamesMulti, 0,
+				columnNamesMulti.length);
+		model.getMultiTable().setColumnIdentifiers(columnNamesMulti);
+		System.arraycopy(tempArray, 18, columnNamesSingle, 0,
+				columnNamesSingle.length);
+		model.getSingleTable().setColumnIdentifiers(columnNamesSingle);
+		model.colNames[0] = tempArray[23];
+		model.colNames[1] = tempArray[24];
+		model.getPropertyTable().setColumnIdentifiers(model.colNames);
+		// Graph
+		elementGraph.setText(tempArray[25]);
+		holonEleNamesDisplayed = tempArray[25];
+		resetGraphBtn.setText(tempArray[26]);
+		// Warning PopUps
+		warningText = tempArray[27];
+		saveBeforeNew = tempArray[28];
+		eraseCategory = tempArray[29];
+		selectObjBeforeErase = tempArray[30];
+		// SimMenu
+		algorithmMenu.algoFolderButton.setText(Languages.getLanguage()[85]);
+		// TimePanel
+		timePanel.playBtn.setToolTipText(Languages.getLanguage()[89]);
+		timePanel.timeResetBtn.setToolTipText(Languages.getLanguage()[90]);
+		timePanel.timeForwardBtn.setToolTipText(Languages.getLanguage()[91]);
+		timePanel.timeBackwardBtn.setToolTipText(Languages.getLanguage()[92]);
+		timePanel.timeSlider.setToolTipText(Languages.getLanguage()[93]);
+		// Image Size Slider
+		lblImageSize.setText(Languages.getLanguage()[94]);
+	}
+
+	/**
+	 * Checks if a double click was made.
+	 *
+	 * @return true if doublecklick, false if not
+	 */
+	private boolean doubleClick() {
+		if (click) {
+			click = false;
+			return true;
+		} else {
+			click = true;
+			Timer t = new Timer("doubleclickTimer", false);
+			t.schedule(new TimerTask() {
+				@Override
+				public void run() {
+					click = false;
+				}
+			}, 350);
+		}
+		return false;
+	}
+
+	/*
+	 * Open a new Tab with an UpperNodeCanvas
+	 */
+	private void openNewUpperNodeTab() {
+		chooseTabTemp();
+
+		JScrollPane scrollPane = getScrollPaneFromTabbedPane();
+		if (scrollPane.getViewport().getComponent(0) instanceof MyCanvas) {
+			unc = new UpperNodeCanvas(model, controller, unitGraph,
+					(CpsUpperNode) temp, "");
+
+		} else {
+			unc = new UpperNodeCanvas(model, controller, unitGraph,
+					(CpsUpperNode) temp, ((UpperNodeCanvas) scrollPane
+							.getViewport().getComponent(0)).path + " -> ");
+		}
+		unc.setShowedInformation(canvas.getShowedInformation());
+
+		// check if tab already open for clicked NodeOfNode
+		boolean dupl = false;
+
+		for (int i = 1; i < tabbedPaneInnerOriginal.getTabCount(); i++) {
+			JScrollPane paneOriginal = (JScrollPane) tabbedPaneInnerOriginal
+					.getComponentAt(i);
+			if (paneOriginal != null
+					&& ((UpperNodeCanvas) paneOriginal.getViewport()
+							.getComponent(0)).upperNode.getId() == temp.getId()) {
+				dupl = true;
+				// set selected component to view
+				tabbedPaneOriginal
+						.setSelectedComponent(tabbedPaneInnerOriginal);
+				// set selected tab in view to found upper-node-canvas
+				tabbedPaneInnerOriginal
+						.setSelectedComponent(tabbedPaneInnerOriginal
+								.getComponentAt(i));
+			}
+
+			if (tabbedPaneSplit.getTabCount() > 0) {
+				JTabbedPane tabbedPaneInnerSplit = (JTabbedPane) tabbedPaneSplit
+						.getComponentAt(0);
+				if (tabbedPaneInnerSplit != null) {
+					JScrollPane paneSplit = (JScrollPane) tabbedPaneInnerSplit
+							.getComponentAt(i);
+					if (!initSplit
+							&& paneSplit != null
+							&& ((UpperNodeCanvas) paneSplit.getViewport()
+									.getComponent(0)).upperNode.getId() == temp
+									.getId()) {
+						dupl = true;
+						// set selected component to view
+						tabbedPaneSplit
+								.setSelectedComponent(tabbedPaneInnerSplit);
+						// set selected tab in view to found upper-node-canvas
+						tabbedPaneInnerSplit
+								.setSelectedComponent(tabbedPaneInnerSplit
+										.getComponentAt(i));
+					}
+				}
+			}
+
+			// if we found a duplicate, break
+			if (dupl) {
+				break;
+			}
+		}
+		if (!dupl) {
+			unc.setBorder(null);
+			unc.setBackground(Color.WHITE);
+			unc.setPreferredSize(new Dimension(model.getCanvasX(), model
+					.getCanvasY()));
+
+			unc.addMouseListener(new MouseAdapter() {
+				@Override
+				public void mousePressed(MouseEvent e) {
+					hideScrollGraph();
+					holonEleNamesDisplayed = Languages.getLanguage()[25];
+					elementGraph.setText(holonEleNamesDisplayed);
+
+					chooseTabTemp();
+
+					JScrollPane scrollPane1 = getScrollPaneFromTabbedPane();
+					temp = ((UpperNodeCanvas) scrollPane1.getViewport()
+							.getComponent(0)).tempCps;
+					if (doubleClick() && MouseEvent.BUTTON3 != e.getButton()
+							&& temp instanceof CpsUpperNode) {
+						openNewUpperNodeTab();
+					}
+					if (temp instanceof HolonSwitch) {
+						unitGraph.repaintWithNewSwitch((HolonSwitch) temp);
+						unitGraph.fillArrayofBooleans();
+					}
+				}
+
+			});
+
+			JScrollPane sp = new JScrollPane(unc);
+			sp.setBorder(null);
+
+			// Selected tabbed Pane = tabbedPaneOriginal or tabbedPaneSplit
+			if (tabTemp == tabbedPaneOriginal) {
+				this.tabbedPaneInnerOriginal.add(temp.getName(), sp);
+				this.tabbedPaneInnerOriginal.setSelectedComponent(sp);
+				this.tabbedPaneInnerOriginal.setTabComponentAt(
+						this.tabbedPaneInnerOriginal.getTabCount() - 1,
+						new ButtonTabComponent(this.tabbedPaneInnerOriginal,
+								tabbedPaneSplit));
+
+			} else {
+				JTabbedPane tabbedPaneInnerSplit = (JTabbedPane) tabbedPaneSplit
+						.getComponentAt(0);
+				tabbedPaneInnerSplit.add(temp.getName(), sp);
+				Component tempC = tabbedPaneInnerSplit.getSelectedComponent();
+				tabbedPaneInnerSplit.setComponentAt(
+						tabbedPaneInnerSplit.getSelectedIndex(), null);
+				tabbedPaneOriginal.setComponentAt(
+						tabbedPaneInnerSplit.getSelectedIndex(), tempC);
+				tabbedPaneInnerSplit.setSelectedComponent(sp);
+
+				tabbedPaneInnerOriginal.add(temp.getName(), null);
+				tabbedPaneInnerOriginal.setTabComponentAt(
+						tabbedPaneInnerOriginal.getTabCount() - 1,
+						new ButtonTabComponent(tabbedPaneInnerOriginal,
+								tabbedPaneInnerSplit));
+			}
+
+			temp = null;
+		}
+	}
+
+	private void updateUpperNodes() {
+		for (Component c : tabbedPaneInnerOriginal.getComponents()) {
+			if (!(c instanceof JScrollPane)) {
+				continue;
+			}
+			Component pane = ((JScrollPane) c).getViewport().getComponent(0);
+			if (pane instanceof UpperNodeCanvas) {
+				temp = model.getHashcodeMap()
+						.get(((UpperNodeCanvas) pane).code);
+				((UpperNodeCanvas) pane).upperNode = (CpsUpperNode) temp;
+			}
+		}
+	}
+
+	/**
+	 * Removes UpperNodeTab if UpperNode was deleted
+	 *
+	 * @param cps
+	 *            the CPS object that is currently selected
+	 */
+	private void removeUpperNodeTab(AbstractCpsObject cps) {
+		if (cps instanceof CpsUpperNode) {
+			boolean splitView = false;
+			for (int i = 1; i < tabbedPaneInnerOriginal.getTabCount(); i++) {
+				JScrollPane scrollPaneOriginal = (JScrollPane) tabbedPaneInnerOriginal
+						.getComponentAt(i);
+
+				if (scrollPaneOriginal == null) {
+					splitView = true;
+				} else if (((UpperNodeCanvas) scrollPaneOriginal.getViewport()
+						.getComponent(0)).upperNode.getId() == cps.getId()) {
+					((ButtonTabComponent) tabbedPaneInnerOriginal
+							.getTabComponentAt(i)).removeTabs();
+					break;
+				}
+			}
+			// If SplitView is on and the view on
+			// tabbedPaneSplit is the deleted upperNode
+			if (splitView && tabbedPaneSplit.getComponentCount() > 0) {
+				JTabbedPane tabbedPaneInnerSplit = (JTabbedPane) tabbedPaneSplit
+						.getComponentAt(0);
+
+				if (((UpperNodeCanvas) ((JScrollPane) tabbedPaneInnerSplit
+						.getSelectedComponent()).getViewport().getComponent(0)).upperNode
+						.getId() == cps.getId()) {
+					((ButtonTabComponent) tabbedPaneInnerOriginal
+							.getTabComponentAt(tabbedPaneInnerSplit
+									.getSelectedIndex())).removeTabs();
+				}
+			}
+		}
+	}
+
+	private void readStatistics(JsonObject json) {
+		List<String> keys = json.entrySet().stream().map(i -> i.getKey())
+				.collect(Collectors.toCollection(ArrayList::new));
+
+		// Saved Values
+		JsonObject obj;
+		AbstractCpsObject cps;
+		int prop;
+		Color color;
+
+		StatisticGraphPanel stat = new StatisticGraphPanel(model, controller,
+				json.get("KEY").getAsString(), model.getGraphTable());
+
+		for (String k : keys) {
+			if (!k.equals("KEY")) {
+				obj = json.get(k).getAsJsonObject();
+				cps = (obj.get("ID") == JsonNull.INSTANCE ? null : controller
+						.searchTracked(obj.get("ID").getAsInt()));
+				prop = obj.get("PROPERTY").getAsInt();
+				color = model.getGson().fromJson(obj.get("COLOR"), Color.class);
+				stat.addObject(new TrackedDataSet(cps, prop, color));
+			}
+			model.getGraphTable().put(json.get("KEY").getAsString(), stat);
+			model.getStatPanel().getGraphPanel().add(stat);
+		}
+	}
+
+	/**
+	 * chooses whether to set the tabTemp to tabbedPaneOriginal or
+	 * tabbedPaneSplit
+	 */
+	private void chooseTabTemp() {
+		// is the uppernode on tabbedPaneOriginal or tabbedPaneSplit
+		if (tabbedPaneOriginal.getMousePosition() != null) {
+			tabTemp = tabbedPaneOriginal;
+		} else {
+			tabTemp = tabbedPaneSplit;
+		}
+	}
+
+	private JScrollPane getScrollPaneFromTabbedPane(JTabbedPane tabbedPane,
+			int index) {
+		tabTemp = tabbedPane;
+		return getScrollPaneFromTabbedPane(index);
+	}
+
+	// private JScrollPane getScrollPaneFromTabbedPane(JTabbedPane tabbedPane) {
+	// return getScrollPaneFromTabbedPane(tabbedPane, -1);
+	// }
+
+	private JScrollPane getScrollPaneFromTabbedPane() {
+		return getScrollPaneFromTabbedPane(-1);
+	}
+
+	private JScrollPane getScrollPaneFromTabbedPane(int index) {
+		Component upperLevelSelectedComponent;
+		if (index == -1) {
+			upperLevelSelectedComponent = tabTemp.getSelectedComponent();
+		} else {
+			upperLevelSelectedComponent = tabTemp.getComponentAt(index);
+		}
+
+		if (upperLevelSelectedComponent instanceof JTabbedPane) {
+			return (JScrollPane) ((JTabbedPane) upperLevelSelectedComponent)
+					.getSelectedComponent();
+		} else if (upperLevelSelectedComponent instanceof JScrollPane) {
+			return (JScrollPane) upperLevelSelectedComponent;
+		} else {
+			return null;
+		}
+	}
+
+	private void repaintGraphAfterUndoRedo() {
+		for (AbstractCpsObject cps : model.getObjectsOnCanvas()) {
+			unitGraph.repaintGraph(cps);
+		}
+	}
+
+	/**
+	 * if flexibility was turned on, then active needs to be turned off, the
+	 * energy currently produced/consumed
+	 *
+	 * @param eleBTemp
+	 *            element that needs to be updated
+	 * @param selectedValueBY
+	 *            the y value in the table
+	 */
+	private void updateElementTableAfterChange(HolonElement eleBTemp,
+			int selectedValueBY) {
+		model.getSingleTable().setValueAt(eleBTemp.isFlexible(),
+				selectedValueBY, 6);
+		model.getSingleTable().setValueAt(eleBTemp.isActive(), selectedValueBY,
+				5);
+		model.getSingleTable().setValueAt(eleBTemp.getAmount(),
+				selectedValueBY, 4);
+		model.getSingleTable().setValueAt(
+				eleBTemp.getFlexibleEnergyAvailablePerElement(),
+				selectedValueBY, 3);
+		model.getSingleTable().setValueAt(eleBTemp.getEnergyPerElement(),
+				selectedValueBY, 2);
+	}
+
+	private void triggerUpdateController(AbstractCpsObject temp) {
+		if (temp != null) {
+			updCon.paintProperties(temp);
+		}
+		updCon.refreshTableHolonElement(model.getMultiTable(),
+				model.getSingleTable());
+		updCon.refreshTableProperties(model.getPropertyTable());
+	}
+
+	/**
+	 * Custom Mouse adapter makes contentPane gain focus once mouse leaves this
+	 * component so copy/paste/cut and "select all" works
+	 */
+	private class FocusCanvasMouseAdapter extends MouseAdapter {
+		@Override
+		public void mouseExited(MouseEvent e) {
+			contentPane.requestFocus();
+		}
+	}
 }