ソースを参照

Adds Supply Bars to partially or not supplied HolonObjects

Andreas T. Meyer-Berg 7 年 前
コミット
9f794b07ab
3 ファイル変更1021 行追加825 行削除
  1. 47 2
      src/classes/HolonObject.java
  2. 37 10
      src/ui/controller/SimulationManager.java
  3. 937 813
      src/ui/view/MyCanvas.java

+ 47 - 2
src/classes/HolonObject.java

@@ -5,6 +5,8 @@ import com.google.gson.annotations.Expose;
 import java.awt.*;
 import java.util.ArrayList;
 
+import javafx.util.converter.PercentageStringConverter;
+
 /**
  * The class HolonObject represents any Object on the system which capability of
  * injecting or consuming energy on the network, for instance a house or a power
@@ -43,7 +45,15 @@ public class HolonObject extends AbstractCpsObject {
     private float totalFlex;
     @Expose
     private int state = 0;
-
+    /**
+     * Energy level that was supplied by other HolonObjects in the current Calculation
+     */
+    private float currentSupply;
+    
+    /**
+     * Percentage of supplied energy of the energy level needed to supply all elements
+     */
+    private float suppliedPercentage;
     /**
      * Constructor Set by default the name of the object equals to the category
      * name, until the user changes it.
@@ -146,12 +156,21 @@ public class HolonObject extends AbstractCpsObject {
      */
     public float getCurrentEnergyAtTimeStep(int x) {
         float temp = 0;
+        float cons = 0, prod = currentSupply;
+        float t;
         for (HolonElement e : getElements()) {
             if (e.isActive()) {
-                temp += e.getOverallEnergyAtTimeStep(x);
+                t = e.getOverallEnergyAtTimeStep(x);
+                if(t<0){
+                	cons+=t;
+                }else{
+                	prod+=t;
+                }
+                temp += t;
             }
         }
         currentEnergy = temp;
+        suppliedPercentage = -prod / cons;
         return currentEnergy;
     }
 
@@ -304,19 +323,24 @@ public class HolonObject extends AbstractCpsObject {
         }
         float minConsum = getElements().get(0).getOverallEnergyAtTimeStep(x);
         float prod = 0;
+        float cons = 0;
         for (HolonElement e : getElements()) {
             if (e.isActive()) {
                 float overallEnergy = e.getOverallEnergyAtTimeStep(x);
                 if (overallEnergy > 0) {
                     prod = prod + overallEnergy;
+                }else{
+                	cons += overallEnergy;
                 }
                 if (minConsum < 0 && (overallEnergy > minConsum && overallEnergy < 0)) {
                     minConsum = overallEnergy;
+                    
                 } else if (minConsum >= 0 && overallEnergy < minConsum) {
                     minConsum = overallEnergy;
                 }
             }
         }
+        suppliedPercentage = -(prod + currentSupply)/cons;
         // System.out.println("minCons: " + minConsum + " prod: " + prod);
         if (minConsum < 0 && prod >= -minConsum) {
             return true;
@@ -513,4 +537,25 @@ public class HolonObject extends AbstractCpsObject {
 
         return sb.toString();
     }
+
+	/**
+	 * @return the {@link #currentSupply}
+	 */
+	public float getCurrentSupply() {
+		return currentSupply;
+	}
+
+	/**
+	 * @param currentSupply the {@link #currentSupply} to set
+	 */
+	public void setCurrentSupply(float currentSupply) {
+		this.currentSupply = currentSupply;
+	}
+	
+	/**
+	 * @return {@link #suppliedPercentage}
+	 */
+	public float getSuppliedPercentage(){
+		return suppliedPercentage;
+	}
 }

+ 37 - 10
src/ui/controller/SimulationManager.java

@@ -91,11 +91,16 @@ public class SimulationManager {
              * 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++) {
@@ -105,17 +110,22 @@ public class SimulationManager {
                             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 += hl.getMinEnergy(x);
+                                    currentProduction += minEnergy;
+                                    hl.setCurrentSupply(-minEnergy);
                             		partiallySuppliedList.add(hl);
                                 } else if (hl.checkIfPartiallySupplied(timeStep)) {
                                     hl.setState(HolonObject.PARTIALLY_SUPPLIED);
-                                    currentProduction += hl.getMinEnergy(x);
+                                    currentProduction += minEnergy;
+                                    hl.setCurrentSupply(-minEnergy);
                             		partiallySuppliedList.add(hl);
                                 } else {
                                 	/**
@@ -123,19 +133,24 @@ public class SimulationManager {
                                 	 */
                                 	if(-hl.getCurrentEnergyAtTimeStep(x)<=currentProduction){
                                 		hl.setState(HolonObject.PARTIALLY_SUPPLIED);
-                                		currentProduction += hl.getMinEnergy(x);
+                                		currentProduction += minEnergy;
+                                		hl.setCurrentSupply(-minEnergy);
                                 		partiallySuppliedList.add(hl);
                                 	}else if(-hl.getMinEnergy(x)<=currentProduction){
                                 		hl.setState(HolonObject.PARTIALLY_SUPPLIED);
-                                		currentProduction += hl.getMinEnergy(x);
+                                		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;
                         }
                     }
@@ -156,16 +171,28 @@ public class SimulationManager {
              * check if some partially supplied building might be fully supplied.
              */
             partiallySuppliedList.sort(new EnergyMinToMaxComparator(x));
-            for(HolonObject part: partiallySuppliedList){
-            	currentProduction -= part.getMinEnergy(x);
+            for(HolonObject hl: partiallySuppliedList){
+            	float minEnergy = hl.getMinEnergy(x);
+            	currentProduction -= minEnergy;
             	/*
             	 * if possible, supply fully
             	 */
-            	if(-part.getCurrentEnergyAtTimeStep(x)<=currentProduction){
-            		part.setState(HolonObject.SUPPLIED);
-            		currentProduction += part.getCurrentEnergyAtTimeStep(x);
+            	float currentEnergyAtTimeStep = hl.getCurrentEnergyAtTimeStep(x);
+				if(-currentEnergyAtTimeStep<=currentProduction){
+            		hl.setState(HolonObject.SUPPLIED);
+            		currentProduction += currentEnergyAtTimeStep;
+            		hl.setCurrentSupply(-currentEnergyAtTimeStep);
+            		 hl.getCurrentEnergyAtTimeStep(x);
             	}else{
-            		currentProduction += part.getMinEnergy(x);
+            		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);
             	}
             }
         }

+ 937 - 813
src/ui/view/MyCanvas.java

@@ -1,17 +1,21 @@
 package ui.view;
 
 import classes.*;
+
 import com.google.gson.JsonParseException;
+
 import ui.controller.Control;
 import ui.controller.UpdateController;
 import ui.model.Model;
 
 import javax.swing.*;
+
 import java.awt.*;
 import java.awt.datatransfer.UnsupportedFlavorException;
 import java.awt.event.MouseEvent;
 import java.awt.event.MouseListener;
 import java.awt.event.MouseMotionListener;
+import java.awt.font.LineMetrics;
 import java.awt.geom.Line2D;
 import java.io.IOException;
 import java.util.ArrayList;
@@ -21,818 +25,938 @@ import java.util.ArrayList;
  *
  * @author Gruppe14
  */
-public class MyCanvas extends AbstractCanvas implements MouseListener, MouseMotionListener {
-
-    private static final long serialVersionUID = 1L;
-
-
-    /**
-     * Constructor.
-     *
-     * @param mod       the Model
-     * @param control   the Controller
-     * @param unitGraph
-     */
-    public MyCanvas(Model mod, Control control, UnitGraph unitGraph) {
-        toolTip = false;
-        this.controller = control;
-        this.model = mod;
-        scalediv20 = model.getScale() / 20;
-
-        showedInformation[0] = true;
-        showedInformation[1] = true;
-        showedInformation[3] = false;
-        showedInformation[4] = true;
-        control.setMaxCapacity(10000);
-
-        popmenu.add(itemCut);
-        popmenu.add(itemCopy);
-        popmenu.add(itemPaste);
-        popmenu.add(itemDelete);
-        popmenu.addSeparator();
-        popmenu.add(itemGroup);
-        popmenu.add(itemUngroup);
-        popmenu.add(itemTrack);
-        popmenu.add(itemUntrack);
-
-        updCon = new UpdateController(mod, control);
-
-        itemDelete.setEnabled(false);
-        itemCut.setEnabled(false);
-        itemCopy.setEnabled(false);
-        itemPaste.setEnabled(true);
-        itemGroup.setEnabled(false);
-        itemUngroup.setEnabled(false);
-        itemTrack.setEnabled(false);
-        itemUntrack.setEnabled(false);
-
-        itemCut.setText(Languages.getLanguage()[95]);
-
-        itemGroup.addActionListener(actionEvent -> {
-            // calculate uppernode pos (taken from the controller)
-            unPos = new Position(0, 0);
-            animCps = new ArrayList<>();
-            for (AbstractCpsObject cps : model.getSelectedCpsObjects()) {
-                animCps.add(cps); // add to animation Cps ArrayList
-                unPos.x += cps.getPosition().x;
-                unPos.y += cps.getPosition().y;
-            }
-            unPos.x /= animCps.size();
-            unPos.y /= animCps.size();
-
-            // save old Position
-            savePos = new ArrayList<>();
-            for (int i = 0; i < animCps.size(); i++) {
-                savePos.add(new Position(0, 0));
-                savePos.get(i).x = animCps.get(i).getPosition().x;
-                savePos.get(i).y = animCps.get(i).getPosition().y;
-            }
-
-            animT = new javax.swing.Timer(animDelay, actionEvent1 -> {
-                if (animDuration - animDelay > 0 && animCps.size() > 1) {
-                    for (AbstractCpsObject animCpObject : animCps) {
-                        double x1 = animCpObject.getPosition().x - unPos.x;
-                        double y1 = animCpObject.getPosition().y - unPos.y;
-                        animCpObject.getPosition().x -= x1 / animSteps;
-                        animCpObject.getPosition().y -= y1 / animSteps;
-                    }
-                    repaint();
-                    animDuration -= animDelay;
-                    animSteps--;
-                } else {
-                    animDuration = ANIMTIME;
-                    animSteps = animDuration / animDelay;
-                    animT.stop();
-                    for (int i = 0; i < animCps.size(); i++) {
-                        animCps.get(i).getPosition().x = savePos.get(i).x;
-                        animCps.get(i).getPosition().y = savePos.get(i).y;
-                    }
-                    controller.addUpperNode("NodeOfNode", null, animCps);
-                    controller.calculateStateForCurrentTimeStep();
-                    triggerUpdateController();
-                    repaint();
-                }
-            });
-            animT.start();
-        });
-
-        itemUngroup.addActionListener(actionEvent -> {
-            // save old Position
-            JTabbedPane tabbedPaneInner = (JTabbedPane) getParent().getParent().getParent();
-            for (int i = 1; i < tabbedPaneInner.getTabCount(); i++) {
-                if (((UpperNodeCanvas) ((JScrollPane) tabbedPaneInner.getComponentAt(i)).getViewport()
-                        .getComponent(0)).upperNode.getId() == tempCps.getId()) {
-                    tabbedPaneInner.remove(i);
-                    break;
-                }
-            }
-
-            savePos = new ArrayList<>();
-            animCps = ((CpsUpperNode) tempCps).getNodes();
-            controller.delUpperNode((CpsUpperNode) tempCps, null);
-
-            for (int i = 0; i < animCps.size(); i++) {
-                savePos.add(new Position(0, 0));
-                savePos.get(i).x = animCps.get(i).getPosition().x;
-                savePos.get(i).y = animCps.get(i).getPosition().y;
-            }
-            for (AbstractCpsObject cps : animCps) {
-                int x = tempCps.getPosition().x;
-                int y = tempCps.getPosition().y;
-
-                cps.setPosition(new Position(x, y));
-            }
-
-            animT = new javax.swing.Timer(animDelay, actionEvent1 -> {
-                if (animDuration - animDelay >= 0) {
-                    for (int i = 0; i < animCps.size(); i++) {
-                        double x1 = animCps.get(i).getPosition().x - savePos.get(i).x;
-                        double y1 = animCps.get(i).getPosition().y - savePos.get(i).y;
-                        animCps.get(i).getPosition().x -= x1 / animSteps;
-                        animCps.get(i).getPosition().y -= y1 / animSteps;
-                    }
-                    repaint();
-                    animDuration -= animDelay;
-                    animSteps--;
-                } else {
-                    animDuration = ANIMTIME;
-                    animSteps = animDuration / animDelay;
-                    animT.stop();
-                    for (int i = 0; i < animCps.size(); i++) {
-                        animCps.get(i).getPosition().x = savePos.get(i).x;
-                        animCps.get(i).getPosition().y = savePos.get(i).y;
-                    }
-
-                    controller.calculateStateForCurrentTimeStep();
-                    triggerUpdateController();
-                    repaint();
-                }
-            });
-            animT.start();
-        });
-
-        // adds the selected object(s) to the statistic panel
-        itemTrack.addActionListener(actionEvent -> {
-            for (AbstractCpsObject o : model.getSelectedCpsObjects()) {
-                boolean found = false;
-                if (controller.getTrackingObj() != null) {
-                    if (controller.getTrackingObj().contains(o)) {
-                        found = true;
-                    }
-                }
-                if (!found) {
-                    controller.addTrackingObj(o);
-                    if (o instanceof HolonObject) {
-                        ((HolonObject) o).updateTrackingInfo();
-                    }
-                }
-                if (model.getShowConsoleLog()) {
-                    controller.addTextToConsole("Tracking: ", Color.BLACK, 12, false, false, false);
-                    controller.addTextToConsole("" + o.getName(), Color.BLUE, 12, true, false, false);
-                    controller.addTextToConsole(", ID:", Color.BLACK, 12, false, false, false);
-                    controller.addTextToConsole("" + o.getId(), Color.RED, 12, true, false, true);
-                }
-            }
-        });
-
-        itemUntrack.addActionListener(actionEvent -> {
-            for (AbstractCpsObject o : model.getSelectedCpsObjects()) {
-                if (o instanceof HolonObject) {
-                    boolean found = false;
-                    if (controller.getTrackingObj() != null) {
-                        for (AbstractCpsObject obj : controller.getTrackingObj()) {
-                            if (obj instanceof HolonObject) {
-                                if (obj.getId() == o.getId()) {
-                                    found = true;
-                                }
-                            }
-                        }
-                    }
-                    if (found) {
-                        // Removed from tracking array and tracking
-                        // information reseted
-                        controller.removeTrackingObj(o);
-                        ((HolonObject) o).setTrackingProd(new float[100]);
-                        ((HolonObject) o).setTrackingCons(new float[100]);
-                    }
-                    if (model.getShowConsoleLog()) {
-                        controller.addTextToConsole("Untracking: ", Color.BLACK, 12, false, false, false);
-                        controller.addTextToConsole("" + o.getName(), Color.BLUE, 12, true, false, false);
-                        controller.addTextToConsole(", ID:", Color.BLACK, 12, false, false, false);
-                        controller.addTextToConsole("" + o.getId(), Color.RED, 12, true, false, true);
-                    }
-                }
-            }
-        });
-
-        itemDelete.addActionListener(actionEvent -> {
-            // Remove the selected Object objects
-        	if(tempCps == null && edgeHighlight != null)
-        	{
-        		controller.removeEdgesOnCanvas(edgeHighlight);
-        		edgeHighlight = null;
-        	}
-            boolean save = false;
-            for (int j = 0; j < model.getSelectedCpsObjects().size(); j++) {
-                AbstractCpsObject cps = model.getSelectedCpsObjects().get(j);
-                if (j == model.getSelectedCpsObjects().size() - 1)
-                    save = true;
-                controller.delCanvasObject(cps, save);
-                controller.removeTrackingObj(cps);
-                // Remove UpperNodeTab if UpperNode deleted
-                if (cps instanceof CpsUpperNode) {
-                    JSplitPane tempSplit = (JSplitPane) getParent().getParent().getParent().getParent();
-                    JTabbedPane tabbedPane;
-                    JTabbedPane tabbedPane2;
-                    // if SplitView is activated
-                    if (tempSplit.getLeftComponent() instanceof JTabbedPane
-                            && tempSplit.getRightComponent() instanceof JTabbedPane) {
-                        tabbedPane = (JTabbedPane) tempSplit.getLeftComponent();
-                        tabbedPane2 = (JTabbedPane) tempSplit.getRightComponent();
-                    } else {
-                        tabbedPane = (JTabbedPane) tempSplit.getLeftComponent();
-                        tabbedPane2 = null;
-                    }
-                    // Look if the uppernode is open in a Tab
-                    for (int i = 4; i < tabbedPane.getTabCount(); i++) {
-                        if (tabbedPane.getComponentAt(i) != null
-                                && ((UpperNodeCanvas) ((JScrollPane) tabbedPane.getComponentAt(i)).getViewport()
-                                .getComponent(0)).upperNode.getId() == cps.getId()) {
-                            ((ButtonTabComponent) tabbedPane.getTabComponentAt(i)).removeTabs();
-                            break;
-                        }
-                    }
-                    // If SplitView is on and the view on
-                    // tabbedPane2 is the deleted upperNode
-                    try {
-                        if (tabbedPane2 != null
-                                && ((UpperNodeCanvas) ((JScrollPane) tabbedPane2.getSelectedComponent())
-                                .getViewport().getComponent(0)).upperNode.getId() == cps.getId()) {
-                            ((ButtonTabComponent) tabbedPane.getTabComponentAt(tabbedPane2.getSelectedIndex()))
-                                    .removeTabs();
-                        }
-                    } catch (Exception e2) {
-                    }
-                }
-                toolTip = false;
-            }
-            model.getSelectedCpsObjects().clear();
-            tempCps = null;
-            repaint();
-        });
-
-        itemCut.addActionListener(actionEvent
-                -> {
-            controller.cut(null);
-            itemPaste.setEnabled(true);
-            repaint();
-        });
-
-        itemCopy.addActionListener(actionEvent -> {
-            controller.copy(null);
-            itemPaste.setEnabled(true);
-            repaint();
-        });
-
-        itemPaste.addActionListener(actionEvent -> {
-            try {
-                controller.paste(null, mousePosition);
-                unitGraph.update(model.getSelectedCpsObjects());
-
-            } catch (JsonParseException | UnsupportedFlavorException | IOException e1) {
-                JLabel message = new JLabel("The Clipboard information cannot be pastet into Application.");
-                JOptionPane.showMessageDialog(null, message, "", JOptionPane.ERROR_MESSAGE);
-            }
-            repaint();
-        });
-
-        this.addMouseListener(this);
-        this.addMouseMotionListener(this);
-    }
-
-    /**
-     * Paints all Components on the Canvas.
-     *
-     * @param g Graphics
-     */
-    public void paintComponent(Graphics g) {
-        String maxCap = null;
-        super.paintComponent(g);
-        // Rendering
-        g2 = (Graphics2D) g;
-        RenderingHints rh = new RenderingHints(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
-        g2.setRenderingHints(rh);
-
-        // Paint the Background
-        if (!model.getCanvasImagePath().isEmpty()) {
-            img = new ImageIcon(model.getCanvasImagePath()).getImage();
-            switch (model.getCanvasImageMode()) {
-                case BackgroundPopUp.IMAGE_PIXELS:
-                    g2.drawImage(img, 0, 0, img.getWidth(null), img.getHeight(null), null);
-                    break;
-                case BackgroundPopUp.STRETCHED:
-                    g2.drawImage(img, 0, 0, model.getCanvasX(), model.getCanvasY(), null);
-                    break;
-                case BackgroundPopUp.CUSTOM:
-                    g2.drawImage(img, 0, 0, model.getCanvasImageWidth(), model.getCanvasImageHeight(), null);
-                    break;
-                default:
-                    break;
-            }
-        }
-
-        // SubNet Coloring
-        int i = 0;
-        for (SubNet s : controller.getSimManager().getSubNets()) {
-
-            if (model.getSubNetColors().size() - 1 < i) {
-                controller.addSubNetColor(new Color((int) (Math.random() * 255), (int) (Math.random() * 255),
-                        (int) (Math.random() * 255)));
-            }
-            if (showedInformation[3]) {
-                for (HolonObject cps : s.getObjects()) {
-                    cps.setBorderColor(model.getSubNetColors().get(i));
-                }
-            }
-            i++;
-        }
-
-        // drawEdges that is being dragged
-        if (drawEdge) {
-            g2.setColor(Color.BLACK);
-            g2.setStroke(new BasicStroke(2));
-            g2.drawLine(tempCps.getPosition().x, tempCps.getPosition().y, x, y);
-        }
-
-        for (CpsEdge con : model.getEdgesOnCanvas()) {
-            maxCap = paintEdge(con, maxCap);
-        }
-
-        // Highlighted Edge
-        if (model.getSelectedObjectID() > 0 || !model.getSelectedCpsObjects().isEmpty() || !tempSelected.isEmpty()) {
-            g2.setColor(Color.BLUE);
-            for (CpsEdge con : model.getEdgesOnCanvas()) {
-                if (con.getFlow() <= con.getCapacity()) {
-                    g2.setStroke(new BasicStroke(Math.min(((con.getFlow() / con.getCapacity() * 3) + 1), 4)));
-                } else {
-                    g2.setStroke(new BasicStroke(2));
-                }
-
-                maxCap = drawEdgeLine(con, maxCap);
-            }
-        } else if (edgeHighlight != null) {
-            g2.setColor(Color.BLUE);
-            if (edgeHighlight.getFlow() <= edgeHighlight.getCapacity()) {
-                g2.setStroke(new BasicStroke(
-                        Math.min(((edgeHighlight.getFlow() / edgeHighlight.getCapacity() * 3) + 1), 4)));
-            } else {
-                g2.setStroke(new BasicStroke(2));
-            }
-            g2.drawLine(edgeHighlight.getA().getPosition().x, edgeHighlight.getA().getPosition().y,
-                    edgeHighlight.getB().getPosition().x, edgeHighlight.getB().getPosition().y);
-
-            maxCap = setCapacityString(edgeHighlight, maxCap);
-
-            if (showedInformation[0]) {
-                g2.drawString(edgeHighlight.getFlow() + "/" + maxCap,
-                        (edgeHighlight.getA().getPosition().x + edgeHighlight.getB().getPosition().x) / 2,
-                        (edgeHighlight.getA().getPosition().y + edgeHighlight.getB().getPosition().y) / 2);
-            }
-        }
-
-        // Objects
-        for (AbstractCpsObject cps : model.getObjectsOnCanvas()) {
-            // Border Highlighting
-            if (showedInformation[3]) {
-                g2.setColor(cps.getBorderColor());
-                if (g2.getColor() != Color.WHITE && !(cps instanceof CpsNode)) {
-                    g2.fillRect((int) (cps.getPosition().x - controller.getScaleDiv2() - scalediv20 - 3),
-                            (int) (cps.getPosition().y - controller.getScaleDiv2() - scalediv20 - 3),
-                            (int) (controller.getScale() + ((scalediv20 + 3) * 2)),
-                            (int) (controller.getScale() + ((scalediv20 + 3) * 2)));
-                }
-            }
-
-            setEdgePictureAndHighlighting(cps);
-
-            g2.drawImage(img, cps.getPosition().x - controller.getScaleDiv2(),
-                    cps.getPosition().y - controller.getScaleDiv2(), controller.getScale(), controller.getScale(),
-                    null);
-
-        }
-
-        // Dragged marker Highlighting
-        if (doMark) {
-            g2.setColor(Color.BLACK);
-            g2.setStroke(new BasicStroke(1));
-            drawMarker();
-        }
-        // Tooltip
-        showTooltip(g);
-    }
-
-    @Override
-    public void mouseClicked(MouseEvent e) {
-        if (e.getButton() == MouseEvent.BUTTON1) {
-            if (model.getPropertyTable().getRowCount() > 0) {
-                for (int i = model.getPropertyTable().getRowCount() - 1; i > -1; i--) {
-                    model.getPropertyTable().removeRow(i);
-                }
-            }
-            triggerUpdateController();
-        }
-    }
-
-    @Override
-    public void mouseEntered(MouseEvent e) {
-    }
-
-    @Override
-    public void mouseExited(MouseEvent e) {
-    }
-
-    @Override
-    public void mousePressed(MouseEvent e) {
-        tempCps = null;
-        edgeHighlight = null;
-        controller.setSelecteEdge(null);
-        // Object Selection
-        for (AbstractCpsObject cps : model.getObjectsOnCanvas()) {
-            cx = cps.getPosition().x - controller.getScaleDiv2();
-            cy = cps.getPosition().y - controller.getScaleDiv2();
-            if (x - controller.getScale() <= cx && y - controller.getScale() <= cy && x >= cx && y >= cy) {
-                tempCps = cps;
-
-                setConsoleTextAfterSelect(cps);
-
-                dragging = true;
-                if (e.isControlDown() && tempCps != null) {
-                    if (model.getSelectedCpsObjects().contains(tempCps)) {
-                        controller.deleteSelectedObject(tempCps);
-                    } else {
-                        controller.addSelectedObject(tempCps);
-                    }
-
-                }
-
-                // If drawing an Edge (CTRL down)
-                if (tempCps.getClass() == HolonObject.class) {
-                    HolonObject tempObj = ((HolonObject) tempCps);
-                    dataSelected = tempObj.getElements();
-                }
-                if (e.isShiftDown()) {
-                    drawEdge = true;
-                    dragging = false;
-                }
-            }
-        }
-
-        // Edge Selection
-        if (tempCps == null) {
-            edgeHighlight = mousePositionOnEdge(x, y);
-            controller.setSelecteEdge(edgeHighlight);
-            controller.setSelectedObjectID(0);
-            if (!e.isControlDown() && e.getButton() != MouseEvent.BUTTON3) {
-                model.getSelectedCpsObjects().clear();
-            }
-        }
-
-        if (edgeHighlight == null && tempCps == null) {
-            sx = e.getX();
-            sy = e.getY();
-            doMark = true;
-        }
-
-        repaint();
-    }
-
-    @Override
-    public void mouseReleased(MouseEvent e) {
-        x = e.getX();
-        y = e.getY();
-
-        dragging = false;
-
-        if (drawEdge) {
-            drawEdge = false;
-            drawDeleteEdge();
-        }
-
-        if (dragged) {
-            try {
-                controller.autoSave();
-            } catch (IOException ex) {
-            	System.err.println("AutoSave error by dragging");
-                ex.printStackTrace();
-            }
-        }
-
-        if (!e.isControlDown() && !dragged && tempCps != null && MouseEvent.BUTTON3 != e.getButton()) {
-            model.getSelectedCpsObjects().clear();
-            controller.addSelectedObject(tempCps);
-        }
-
-        dragged = false;
-
-        // Rightclick List
-        setRightClickMenu(e);
-
-        markObjects();
-
-        if (doubleClick() && tempCps != null && tempCps instanceof HolonSwitch && MouseEvent.BUTTON3 != e.getButton()) {
-            ((HolonSwitch) tempCps).switchState();
-        }
-
-        controller.calculateStateForTimeStep(model.getCurIteration());
-
-        triggerUpdateController();
-
-        repaint();
-
-    }
-
-    @Override
-    public void mouseDragged(MouseEvent e) {
-        // If Edge is drawn
-        x = e.getX();
-        y = e.getY();
-        if (!model.getSelectedCpsObjects().contains(tempCps) && !doMark) {
-            model.getSelectedCpsObjects().clear();
-            if (tempCps != null) {
-                controller.addSelectedObject(tempCps);
-            }
-        }
-        if (dragging) {
-            try {
-                dragged = true;
-                float xDist, yDist; // Distance
-
-                x = e.getX();
-                y = e.getY();
-
-                // Make sure its in bounds
-                if (e.getX() < controller.getScaleDiv2())
-                    x = controller.getScaleDiv2();
-                else if (e.getX() > this.getWidth() - controller.getScaleDiv2())
-                    x = this.getWidth() - controller.getScaleDiv2();
-                if (e.getY() < controller.getScaleDiv2())
-                    y = controller.getScaleDiv2();
-                else if (e.getY() > this.getHeight() - controller.getScaleDiv2())
-                    y = this.getHeight() - controller.getScaleDiv2();
-
-                // Distance
-                xDist = x - tempCps.getPosition().x;
-                yDist = y - tempCps.getPosition().y;
-
-                tempCps.setPosition(x, y); // Drag Position
-                // ToolTipText Position and name
-                toolTip = true;
-                toolTipText = tempCps.getName() + ", " + tempCps.getId();
-                toolTipPos.x = tempCps.getPosition().x - controller.getScaleDiv2();
-                toolTipPos.y = tempCps.getPosition().y + controller.getScaleDiv2();
-
-                // All Selected Objects
-                for (AbstractCpsObject cps : model.getSelectedCpsObjects()) {
-                    if (cps != tempCps) {
-                        x = (int) (cps.getPosition().x + xDist);
-                        y = (int) (cps.getPosition().y + yDist);
-
-                        // Make sure its in bounds
-                        if (x <= controller.getScaleDiv2())
-                            x = controller.getScaleDiv2();
-                        else if (x > this.getWidth() - controller.getScaleDiv2())
-                            x = this.getWidth() - controller.getScaleDiv2();
-                        if (y <= controller.getScaleDiv2())
-                            y = controller.getScaleDiv2();
-                        else if (y > this.getHeight() - controller.getScaleDiv2())
-                            y = this.getHeight() - controller.getScaleDiv2();
-
-                        cps.setPosition(x, y);
-                    }
-                }
-                repaint();
-            } catch (Exception eex) {
-            }
-        }
-
-        // Mark Objects
-        if (doMark) {
-            tempSelected.clear();
-            for (AbstractCpsObject cps : model.getObjectsOnCanvas()) {
-                int x1 = sx, x2 = x, y1 = sy, y2 = y;
-
-                if (sx >= x) {
-                    x1 = x;
-                    x2 = sx;
-                }
-                if (sy >= y) {
-                    y1 = y;
-                    y2 = sy;
-                }
-                if (x1 <= cps.getPosition().x + model.getScaleDiv2() && y1 <= cps.getPosition().y + model.getScaleDiv2()
-                        && x2 >= cps.getPosition().x && y2 >= cps.getPosition().y) {
-                    tempSelected.add(cps);
-
-                }
-            }
-        }
-
-        repaint();
-
-    }
-
-    @Override
-    public void mouseMoved(MouseEvent e) {
-        x = e.getX();
-        y = e.getY();
-
-        // Everything for the tooltip :)
-        boolean on = false;
-        for (AbstractCpsObject cps : model.getObjectsOnCanvas()) {
-            cx = cps.getPosition().x - controller.getScaleDiv2();
-            cy = cps.getPosition().y - controller.getScaleDiv2();
-
-            on = setToolTipInfoAndPosition(on, cps);
-        }
-        toolTip = on;
-        repaint();
-    }
-
-    /**
-     * Draws or Deletes an Edge.
-     */
-    void drawDeleteEdge() {
-        if (getMousePosition() != null) {
-            boolean node = true;
-            boolean newEdge = true;
-            boolean onEdge = true;
-            boolean deleteNode = false;
-            CpsEdge e = null;
-
-            for (AbstractCpsObject cps : model.getObjectsOnCanvas()) {
-                cx = cps.getPosition().x - controller.getScaleDiv2();
-                cy = cps.getPosition().y - controller.getScaleDiv2();
-                if (x - controller.getScale() <= cx
-                        && y - controller.getScale() <= cy
-                        && x >= cx && y >= cy
-                        && cps != tempCps) {
-                    node = false;
-                    onEdge = false;
-                    for (CpsEdge p : tempCps.getConnections()) {
-                        if ((p.getA() == tempCps && p.getB() == cps) || (p.getB() == tempCps && p.getA() == cps)) {
-                            newEdge = false;
-                            e = p;
-                        }
-                    }
-                    if (!newEdge) {
-                        controller.removeEdgesOnCanvas(e);
-                        // Node ohne Edge?
-                        if (e.getA().getClass() == CpsNode.class && e.getA().getConnections().isEmpty()) {
-                            tempCps = e.getA();
-                            deleteNode = true;
-                        }
-                        if (e.getB().getClass() == CpsNode.class && e.getB().getConnections().isEmpty()) {
-                            deleteNode = true;
-                        }
-                    } else {
-                        e = new CpsEdge(cps, tempCps, model.getMaxCapacity());
-                        controller.addEdgeOnCanvas(e);
-                    }
-                }
-            }
-            // Edge auf eine Edge gezogen?
-            if (onEdge) {
-                CpsEdge p = mousePositionOnEdge(x, y);
-                if (p != null) {
-                    CpsEdge e1;
-                    CpsEdge e2;
-
-                    node = false;
-
-                    CpsNode n = new CpsNode("Node");
-
-                    n.setPosition(x, y);
-                    controller.addObjectCanvas(n);
-
-                    AbstractCpsObject r, k;
-                    r = p.getA();
-                    k = p.getB();
-
-                    e = new CpsEdge(n, tempCps, model.getMaxCapacity());
-
-                    e1 = new CpsEdge(n, r, model.getMaxCapacity());
-
-                    e2 = new CpsEdge(n, k, model.getMaxCapacity());
-
-                    controller.removeEdgesOnCanvas(p);
-                    controller.addEdgeOnCanvas(e);
-                    controller.addEdgeOnCanvas(e1);
-                    controller.addEdgeOnCanvas(e2);
-                }
-            }
-
-            // ins leere Gedragged
-            if (node) {
-                CpsNode n = new CpsNode("Node");
-
-                n.setPosition(x, y);
-                controller.addObjectCanvas(n);
-
-                e = new CpsEdge(n, tempCps, model.getMaxCapacity());
-
-                controller.addEdgeOnCanvas(e);
-            }
-
-            // Wenn ein Node ohne Connections da ist
-            if (deleteNode) {
-                controller.delCanvasObject(tempCps, true);
-                tempCps = null;
-            }
-        }
-    }
-
-    /**
-     * Checks if the mouse is on an Edge.
-     *
-     * @param x Position of the Mouse
-     * @param y Position of the Mouse
-     * @return CpsEdge the Mouse is on, null if the mouse is not on an Edge
-     */
-    private CpsEdge mousePositionOnEdge(int x, int y) {
-        x += controller.getScaleDiv2();
-        y += controller.getScaleDiv2();
-        for (CpsEdge p : model.getEdgesOnCanvas()) {
-            Line2D l = new Line2D.Float(p.getA().getPosition().x, p.getA().getPosition().y, p.getB().getPosition().x,
-                    p.getB().getPosition().y);
-
-            int[] positions = determineMousePositionOnEdge(p);
-            int lx = positions[0];
-            int ly = positions[1];
-            int hx = positions[2];
-            int hy = positions[3];
-
-            // distance from a point to a line and between both Objects
-            if (l.ptLineDistSq(x - model.getScaleDiv2(), y - model.getScaleDiv2()) < 20 && x > lx && x < hx && y > ly
-                    && y < hy) {
-                return p;
-            }
-        }
-        return null;
-    }
-    
-
-    void updateLanguages() {
-        itemCut.setText(Languages.getLanguage()[95]);
-        itemCopy.setText(Languages.getLanguage()[96]);
-        itemPaste.setText(Languages.getLanguage()[97]);
-        itemDelete.setText(Languages.getLanguage()[98]);
-        itemGroup.setText(Languages.getLanguage()[99]);
-        itemUngroup.setText(Languages.getLanguage()[100]);
-        itemTrack.setText(Languages.getLanguage()[101]);
-        itemUntrack.setText(Languages.getLanguage()[102]);
-    }
-
-    /**
-     * Set if Information should be shown.
-     *
-     * @param connection boolean for conecction
-     * @param object     boolean for objects
-     * @param nodeOfnode
-     */
-    void setShowedInformation(boolean connection, boolean object, boolean border, boolean nodeOfnode) {
-        showedInformation[0] = connection;
-        showedInformation[1] = object;
-        showedInformation[3] = border;
-        showedInformation[4] = nodeOfnode;
-    }
-
-    /**
-     * Returns if Information should be shown.
-     *
-     * @return Array of boolean [0] = connection, [1] = objects
-     */
-    boolean[] getShowedInformation() {
-        return showedInformation;
-    }
-
-    /**
-     * set toolTip
-     *
-     * @param bool
-     */
-    void setToolTip(boolean bool) {
-        this.toolTip = bool;
-    }
-
-    /**
-     * Set the Mouse
-     *
-     * @param x
-     * @param y
-     */
-    void setXY(int x, int y) {
-        this.x = x;
-        this.y = y;
-    }
+public class MyCanvas extends AbstractCanvas implements MouseListener,
+		MouseMotionListener {
+
+	private static final long serialVersionUID = 1L;
+
+	/**
+	 * Constructor.
+	 *
+	 * @param mod
+	 *            the Model
+	 * @param control
+	 *            the Controller
+	 * @param unitGraph
+	 */
+	public MyCanvas(Model mod, Control control, UnitGraph unitGraph) {
+		toolTip = false;
+		this.controller = control;
+		this.model = mod;
+		scalediv20 = model.getScale() / 20;
+
+		showedInformation[0] = true;
+		showedInformation[1] = true;
+		showedInformation[3] = false;
+		showedInformation[4] = true;
+		control.setMaxCapacity(10000);
+
+		popmenu.add(itemCut);
+		popmenu.add(itemCopy);
+		popmenu.add(itemPaste);
+		popmenu.add(itemDelete);
+		popmenu.addSeparator();
+		popmenu.add(itemGroup);
+		popmenu.add(itemUngroup);
+		popmenu.add(itemTrack);
+		popmenu.add(itemUntrack);
+
+		updCon = new UpdateController(mod, control);
+
+		itemDelete.setEnabled(false);
+		itemCut.setEnabled(false);
+		itemCopy.setEnabled(false);
+		itemPaste.setEnabled(true);
+		itemGroup.setEnabled(false);
+		itemUngroup.setEnabled(false);
+		itemTrack.setEnabled(false);
+		itemUntrack.setEnabled(false);
+
+		itemCut.setText(Languages.getLanguage()[95]);
+
+		itemGroup.addActionListener(actionEvent -> {
+			// calculate uppernode pos (taken from the controller)
+				unPos = new Position(0, 0);
+				animCps = new ArrayList<>();
+				for (AbstractCpsObject cps : model.getSelectedCpsObjects()) {
+					animCps.add(cps); // add to animation Cps ArrayList
+					unPos.x += cps.getPosition().x;
+					unPos.y += cps.getPosition().y;
+				}
+				unPos.x /= animCps.size();
+				unPos.y /= animCps.size();
+
+				// save old Position
+				savePos = new ArrayList<>();
+				for (int i = 0; i < animCps.size(); i++) {
+					savePos.add(new Position(0, 0));
+					savePos.get(i).x = animCps.get(i).getPosition().x;
+					savePos.get(i).y = animCps.get(i).getPosition().y;
+				}
+
+				animT = new javax.swing.Timer(animDelay, actionEvent1 -> {
+					if (animDuration - animDelay > 0 && animCps.size() > 1) {
+						for (AbstractCpsObject animCpObject : animCps) {
+							double x1 = animCpObject.getPosition().x - unPos.x;
+							double y1 = animCpObject.getPosition().y - unPos.y;
+							animCpObject.getPosition().x -= x1 / animSteps;
+							animCpObject.getPosition().y -= y1 / animSteps;
+						}
+						repaint();
+						animDuration -= animDelay;
+						animSteps--;
+					} else {
+						animDuration = ANIMTIME;
+						animSteps = animDuration / animDelay;
+						animT.stop();
+						for (int i = 0; i < animCps.size(); i++) {
+							animCps.get(i).getPosition().x = savePos.get(i).x;
+							animCps.get(i).getPosition().y = savePos.get(i).y;
+						}
+						controller.addUpperNode("NodeOfNode", null, animCps);
+						controller.calculateStateForCurrentTimeStep();
+						triggerUpdateController();
+						repaint();
+					}
+				});
+				animT.start();
+			});
+
+		itemUngroup
+				.addActionListener(actionEvent -> {
+					// save old Position
+					JTabbedPane tabbedPaneInner = (JTabbedPane) getParent()
+							.getParent().getParent();
+					for (int i = 1; i < tabbedPaneInner.getTabCount(); i++) {
+						if (((UpperNodeCanvas) ((JScrollPane) tabbedPaneInner
+								.getComponentAt(i)).getViewport().getComponent(
+								0)).upperNode.getId() == tempCps.getId()) {
+							tabbedPaneInner.remove(i);
+							break;
+						}
+					}
+
+					savePos = new ArrayList<>();
+					animCps = ((CpsUpperNode) tempCps).getNodes();
+					controller.delUpperNode((CpsUpperNode) tempCps, null);
+
+					for (int i = 0; i < animCps.size(); i++) {
+						savePos.add(new Position(0, 0));
+						savePos.get(i).x = animCps.get(i).getPosition().x;
+						savePos.get(i).y = animCps.get(i).getPosition().y;
+					}
+					for (AbstractCpsObject cps : animCps) {
+						int x = tempCps.getPosition().x;
+						int y = tempCps.getPosition().y;
+
+						cps.setPosition(new Position(x, y));
+					}
+
+					animT = new javax.swing.Timer(
+							animDelay,
+							actionEvent1 -> {
+								if (animDuration - animDelay >= 0) {
+									for (int i = 0; i < animCps.size(); i++) {
+										double x1 = animCps.get(i)
+												.getPosition().x
+												- savePos.get(i).x;
+										double y1 = animCps.get(i)
+												.getPosition().y
+												- savePos.get(i).y;
+										animCps.get(i).getPosition().x -= x1
+												/ animSteps;
+										animCps.get(i).getPosition().y -= y1
+												/ animSteps;
+									}
+									repaint();
+									animDuration -= animDelay;
+									animSteps--;
+								} else {
+									animDuration = ANIMTIME;
+									animSteps = animDuration / animDelay;
+									animT.stop();
+									for (int i = 0; i < animCps.size(); i++) {
+										animCps.get(i).getPosition().x = savePos
+												.get(i).x;
+										animCps.get(i).getPosition().y = savePos
+												.get(i).y;
+									}
+
+									controller
+											.calculateStateForCurrentTimeStep();
+									triggerUpdateController();
+									repaint();
+								}
+							});
+					animT.start();
+				});
+
+		// adds the selected object(s) to the statistic panel
+		itemTrack.addActionListener(actionEvent -> {
+			for (AbstractCpsObject o : model.getSelectedCpsObjects()) {
+				boolean found = false;
+				if (controller.getTrackingObj() != null) {
+					if (controller.getTrackingObj().contains(o)) {
+						found = true;
+					}
+				}
+				if (!found) {
+					controller.addTrackingObj(o);
+					if (o instanceof HolonObject) {
+						((HolonObject) o).updateTrackingInfo();
+					}
+				}
+				if (model.getShowConsoleLog()) {
+					controller.addTextToConsole("Tracking: ", Color.BLACK, 12,
+							false, false, false);
+					controller.addTextToConsole("" + o.getName(), Color.BLUE,
+							12, true, false, false);
+					controller.addTextToConsole(", ID:", Color.BLACK, 12,
+							false, false, false);
+					controller.addTextToConsole("" + o.getId(), Color.RED, 12,
+							true, false, true);
+				}
+			}
+		});
+
+		itemUntrack.addActionListener(actionEvent -> {
+			for (AbstractCpsObject o : model.getSelectedCpsObjects()) {
+				if (o instanceof HolonObject) {
+					boolean found = false;
+					if (controller.getTrackingObj() != null) {
+						for (AbstractCpsObject obj : controller
+								.getTrackingObj()) {
+							if (obj instanceof HolonObject) {
+								if (obj.getId() == o.getId()) {
+									found = true;
+								}
+							}
+						}
+					}
+					if (found) {
+						// Removed from tracking array and tracking
+						// information reseted
+				controller.removeTrackingObj(o);
+				((HolonObject) o).setTrackingProd(new float[100]);
+				((HolonObject) o).setTrackingCons(new float[100]);
+			}
+			if (model.getShowConsoleLog()) {
+				controller.addTextToConsole("Untracking: ", Color.BLACK, 12,
+						false, false, false);
+				controller.addTextToConsole("" + o.getName(), Color.BLUE, 12,
+						true, false, false);
+				controller.addTextToConsole(", ID:", Color.BLACK, 12, false,
+						false, false);
+				controller.addTextToConsole("" + o.getId(), Color.RED, 12,
+						true, false, true);
+			}
+		}
+	}
+})		;
+
+		itemDelete.addActionListener(actionEvent -> {
+			// Remove the selected Object objects
+				if (tempCps == null && edgeHighlight != null) {
+					controller.removeEdgesOnCanvas(edgeHighlight);
+					edgeHighlight = null;
+				}
+				boolean save = false;
+				for (int j = 0; j < model.getSelectedCpsObjects().size(); j++) {
+					AbstractCpsObject cps = model.getSelectedCpsObjects()
+							.get(j);
+					if (j == model.getSelectedCpsObjects().size() - 1)
+						save = true;
+					controller.delCanvasObject(cps, save);
+					controller.removeTrackingObj(cps);
+					// Remove UpperNodeTab if UpperNode deleted
+				if (cps instanceof CpsUpperNode) {
+					JSplitPane tempSplit = (JSplitPane) getParent().getParent()
+							.getParent().getParent();
+					JTabbedPane tabbedPane;
+					JTabbedPane tabbedPane2;
+					// if SplitView is activated
+					if (tempSplit.getLeftComponent() instanceof JTabbedPane
+							&& tempSplit.getRightComponent() instanceof JTabbedPane) {
+						tabbedPane = (JTabbedPane) tempSplit.getLeftComponent();
+						tabbedPane2 = (JTabbedPane) tempSplit
+								.getRightComponent();
+					} else {
+						tabbedPane = (JTabbedPane) tempSplit.getLeftComponent();
+						tabbedPane2 = null;
+					}
+					// Look if the uppernode is open in a Tab
+					for (int i = 4; i < tabbedPane.getTabCount(); i++) {
+						if (tabbedPane.getComponentAt(i) != null
+								&& ((UpperNodeCanvas) ((JScrollPane) tabbedPane
+										.getComponentAt(i)).getViewport()
+										.getComponent(0)).upperNode.getId() == cps
+										.getId()) {
+							((ButtonTabComponent) tabbedPane
+									.getTabComponentAt(i)).removeTabs();
+							break;
+						}
+					}
+					// If SplitView is on and the view on
+					// tabbedPane2 is the deleted upperNode
+					try {
+						if (tabbedPane2 != null
+								&& ((UpperNodeCanvas) ((JScrollPane) tabbedPane2
+										.getSelectedComponent()).getViewport()
+										.getComponent(0)).upperNode.getId() == cps
+										.getId()) {
+							((ButtonTabComponent) tabbedPane
+									.getTabComponentAt(tabbedPane2
+											.getSelectedIndex())).removeTabs();
+						}
+					} catch (Exception e2) {
+					}
+				}
+				toolTip = false;
+			}
+			model.getSelectedCpsObjects().clear();
+			tempCps = null;
+			repaint();
+		});
+
+		itemCut.addActionListener(actionEvent -> {
+			controller.cut(null);
+			itemPaste.setEnabled(true);
+			repaint();
+		});
+
+		itemCopy.addActionListener(actionEvent -> {
+			controller.copy(null);
+			itemPaste.setEnabled(true);
+			repaint();
+		});
+
+		itemPaste
+				.addActionListener(actionEvent -> {
+					try {
+						controller.paste(null, mousePosition);
+						unitGraph.update(model.getSelectedCpsObjects());
+
+					} catch (JsonParseException | UnsupportedFlavorException
+							| IOException e1) {
+						JLabel message = new JLabel(
+								"The Clipboard information cannot be pastet into Application.");
+						JOptionPane.showMessageDialog(null, message, "",
+								JOptionPane.ERROR_MESSAGE);
+					}
+					repaint();
+				});
+
+		this.addMouseListener(this);
+		this.addMouseMotionListener(this);
+	}
+
+	/**
+	 * Paints all Components on the Canvas.
+	 *
+	 * @param g
+	 *            Graphics
+	 */
+	public void paintComponent(Graphics g) {
+		String maxCap = null;
+		super.paintComponent(g);
+		// Rendering
+		g2 = (Graphics2D) g;
+		RenderingHints rh = new RenderingHints(RenderingHints.KEY_ANTIALIASING,
+				RenderingHints.VALUE_ANTIALIAS_ON);
+		g2.setRenderingHints(rh);
+
+		// Paint the Background
+		if (!model.getCanvasImagePath().isEmpty()) {
+			img = new ImageIcon(model.getCanvasImagePath()).getImage();
+			switch (model.getCanvasImageMode()) {
+			case BackgroundPopUp.IMAGE_PIXELS:
+				g2.drawImage(img, 0, 0, img.getWidth(null),
+						img.getHeight(null), null);
+				break;
+			case BackgroundPopUp.STRETCHED:
+				g2.drawImage(img, 0, 0, model.getCanvasX(), model.getCanvasY(),
+						null);
+				break;
+			case BackgroundPopUp.CUSTOM:
+				g2.drawImage(img, 0, 0, model.getCanvasImageWidth(),
+						model.getCanvasImageHeight(), null);
+				break;
+			default:
+				break;
+			}
+		}
+
+		// SubNet Coloring
+		int i = 0;
+		for (SubNet s : controller.getSimManager().getSubNets()) {
+
+			if (model.getSubNetColors().size() - 1 < i) {
+				controller.addSubNetColor(new Color(
+						(int) (Math.random() * 255),
+						(int) (Math.random() * 255),
+						(int) (Math.random() * 255)));
+			}
+			if (showedInformation[3]) {
+				for (HolonObject cps : s.getObjects()) {
+					cps.setBorderColor(model.getSubNetColors().get(i));
+				}
+			}
+			i++;
+		}
+
+		// drawEdges that is being dragged
+		if (drawEdge) {
+			g2.setColor(Color.BLACK);
+			g2.setStroke(new BasicStroke(2));
+			g2.drawLine(tempCps.getPosition().x, tempCps.getPosition().y, x, y);
+		}
+
+		for (CpsEdge con : model.getEdgesOnCanvas()) {
+			maxCap = paintEdge(con, maxCap);
+		}
+
+		// Highlighted Edge
+		if (model.getSelectedObjectID() > 0
+				|| !model.getSelectedCpsObjects().isEmpty()
+				|| !tempSelected.isEmpty()) {
+			g2.setColor(Color.BLUE);
+			for (CpsEdge con : model.getEdgesOnCanvas()) {
+				if (con.getFlow() <= con.getCapacity()) {
+					g2.setStroke(new BasicStroke(Math.min(
+							((con.getFlow() / con.getCapacity() * 3) + 1), 4)));
+				} else {
+					g2.setStroke(new BasicStroke(2));
+				}
+
+				maxCap = drawEdgeLine(con, maxCap);
+			}
+		} else if (edgeHighlight != null) {
+			g2.setColor(Color.BLUE);
+			if (edgeHighlight.getFlow() <= edgeHighlight.getCapacity()) {
+				g2.setStroke(new BasicStroke(Math.min(((edgeHighlight.getFlow()
+						/ edgeHighlight.getCapacity() * 3) + 1), 4)));
+			} else {
+				g2.setStroke(new BasicStroke(2));
+			}
+			g2.drawLine(edgeHighlight.getA().getPosition().x, edgeHighlight
+					.getA().getPosition().y,
+					edgeHighlight.getB().getPosition().x, edgeHighlight.getB()
+							.getPosition().y);
+
+			maxCap = setCapacityString(edgeHighlight, maxCap);
+
+			if (showedInformation[0]) {
+				g2.drawString(edgeHighlight.getFlow() + "/" + maxCap,
+						(edgeHighlight.getA().getPosition().x + edgeHighlight
+								.getB().getPosition().x) / 2, (edgeHighlight
+								.getA().getPosition().y + edgeHighlight.getB()
+								.getPosition().y) / 2);
+			}
+		}
+
+		// Objects
+		for (AbstractCpsObject cps : model.getObjectsOnCanvas()) {
+			// Border Highlighting
+			if (showedInformation[3]) {
+				g2.setColor(cps.getBorderColor());
+				if (g2.getColor() != Color.WHITE && !(cps instanceof CpsNode)) {
+					g2.fillRect(
+							(int) (cps.getPosition().x
+									- controller.getScaleDiv2() - scalediv20 - 3),
+							(int) (cps.getPosition().y
+									- controller.getScaleDiv2() - scalediv20 - 3),
+							(int) (controller.getScale() + ((scalediv20 + 3) * 2)),
+							(int) (controller.getScale() + ((scalediv20 + 3) * 2)));
+				}
+			}
+
+			setEdgePictureAndHighlighting(cps);
+
+			g2.drawImage(img, cps.getPosition().x - controller.getScaleDiv2(),
+					cps.getPosition().y - controller.getScaleDiv2(),
+					controller.getScale(), controller.getScale(), null);
+
+			/**
+			 * draw and fill the supply Bar //TODO: work in Progress
+			 */
+			if (cps instanceof HolonObject) {
+				HolonObject hl = (HolonObject) cps;
+				if (hl != null
+						&& (hl.getState() == HolonObject.NOT_SUPPLIED || hl
+								.getState() == HolonObject.PARTIALLY_SUPPLIED)) {
+					// calculate Positons:
+					int barX = (int) (cps.getPosition().x
+							- controller.getScaleDiv2() - scalediv20);
+					int barY = (int) (cps.getPosition().y
+							- controller.getScaleDiv2() + controller.getScale() + 1);
+					int barWidth = (int) (controller.getScale()
+							+ ((scalediv20) * 2) - 1);
+					int barHeight = (int) (controller.getScale() / 5);
+
+					// draw Rectangle under the image
+					g2.setStroke(new BasicStroke(1));
+					g2.drawRect(barX, barY, barWidth, barHeight);
+
+					// get supplied status
+					float percentage = hl.getSuppliedPercentage();
+
+					// set Color
+					g2.setColor(hl.getColor());
+
+					// fill it accordingly
+					g2.fillRect(barX + 1, barY + 1,
+							(int) ((barWidth - 1) * percentage), barHeight - 1);
+
+					// write percentage
+					g2.setColor(Color.BLACK);
+					Font oldFont = g2.getFont();
+					g.setFont(new Font("TimesRoman", Font.PLAIN,
+							(int) (barHeight * 1.5) - 2));
+
+					String percentageString = (Math.round((percentage * 100)))
+							+ "%";
+
+					int stringWidth = (int) g2.getFontMetrics()
+							.getStringBounds(percentageString, g2).getWidth();
+					g2.drawString(percentageString, barX + barWidth / 2 + 1
+							- stringWidth / 2, barY + barHeight);
+
+					g2.setFont(oldFont);
+				}
+			}
+
+		}
+
+		// Dragged marker Highlighting
+		if (doMark) {
+			g2.setColor(Color.BLACK);
+			g2.setStroke(new BasicStroke(0));
+			drawMarker();
+		}
+		// Tooltip
+		showTooltip(g);
+	}
+
+	@Override
+	public void mouseClicked(MouseEvent e) {
+		if (e.getButton() == MouseEvent.BUTTON1) {
+			if (model.getPropertyTable().getRowCount() > 0) {
+				for (int i = model.getPropertyTable().getRowCount() - 1; i > -1; i--) {
+					model.getPropertyTable().removeRow(i);
+				}
+			}
+			triggerUpdateController();
+		}
+	}
+
+	@Override
+	public void mouseEntered(MouseEvent e) {
+	}
+
+	@Override
+	public void mouseExited(MouseEvent e) {
+	}
+
+	@Override
+	public void mousePressed(MouseEvent e) {
+		tempCps = null;
+		edgeHighlight = null;
+		controller.setSelecteEdge(null);
+		// Object Selection
+		for (AbstractCpsObject cps : model.getObjectsOnCanvas()) {
+			cx = cps.getPosition().x - controller.getScaleDiv2();
+			cy = cps.getPosition().y - controller.getScaleDiv2();
+			if (x - controller.getScale() <= cx
+					&& y - controller.getScale() <= cy && x >= cx && y >= cy) {
+				tempCps = cps;
+
+				setConsoleTextAfterSelect(cps);
+
+				dragging = true;
+				if (e.isControlDown() && tempCps != null) {
+					if (model.getSelectedCpsObjects().contains(tempCps)) {
+						controller.deleteSelectedObject(tempCps);
+					} else {
+						controller.addSelectedObject(tempCps);
+					}
+
+				}
+
+				// If drawing an Edge (CTRL down)
+				if (tempCps.getClass() == HolonObject.class) {
+					HolonObject tempObj = ((HolonObject) tempCps);
+					dataSelected = tempObj.getElements();
+				}
+				if (e.isShiftDown()) {
+					drawEdge = true;
+					dragging = false;
+				}
+			}
+		}
+
+		// Edge Selection
+		if (tempCps == null) {
+			edgeHighlight = mousePositionOnEdge(x, y);
+			controller.setSelecteEdge(edgeHighlight);
+			controller.setSelectedObjectID(0);
+			if (!e.isControlDown() && e.getButton() != MouseEvent.BUTTON3) {
+				model.getSelectedCpsObjects().clear();
+			}
+		}
+
+		if (edgeHighlight == null && tempCps == null) {
+			sx = e.getX();
+			sy = e.getY();
+			doMark = true;
+		}
+
+		repaint();
+	}
+
+	@Override
+	public void mouseReleased(MouseEvent e) {
+		x = e.getX();
+		y = e.getY();
+
+		dragging = false;
+
+		if (drawEdge) {
+			drawEdge = false;
+			drawDeleteEdge();
+		}
+
+		if (dragged) {
+			try {
+				controller.autoSave();
+			} catch (IOException ex) {
+				System.err.println("AutoSave error by dragging");
+				ex.printStackTrace();
+			}
+		}
+
+		if (!e.isControlDown() && !dragged && tempCps != null
+				&& MouseEvent.BUTTON3 != e.getButton()) {
+			model.getSelectedCpsObjects().clear();
+			controller.addSelectedObject(tempCps);
+		}
+
+		dragged = false;
+
+		// Rightclick List
+		setRightClickMenu(e);
+
+		markObjects();
+
+		if (doubleClick() && tempCps != null && tempCps instanceof HolonSwitch
+				&& MouseEvent.BUTTON3 != e.getButton()) {
+			((HolonSwitch) tempCps).switchState();
+		}
+
+		controller.calculateStateForTimeStep(model.getCurIteration());
+
+		triggerUpdateController();
+
+		repaint();
+
+	}
+
+	@Override
+	public void mouseDragged(MouseEvent e) {
+		// If Edge is drawn
+		x = e.getX();
+		y = e.getY();
+		if (!model.getSelectedCpsObjects().contains(tempCps) && !doMark) {
+			model.getSelectedCpsObjects().clear();
+			if (tempCps != null) {
+				controller.addSelectedObject(tempCps);
+			}
+		}
+		if (dragging) {
+			try {
+				dragged = true;
+				float xDist, yDist; // Distance
+
+				x = e.getX();
+				y = e.getY();
+
+				// Make sure its in bounds
+				if (e.getX() < controller.getScaleDiv2())
+					x = controller.getScaleDiv2();
+				else if (e.getX() > this.getWidth() - controller.getScaleDiv2())
+					x = this.getWidth() - controller.getScaleDiv2();
+				if (e.getY() < controller.getScaleDiv2())
+					y = controller.getScaleDiv2();
+				else if (e.getY() > this.getHeight()
+						- controller.getScaleDiv2())
+					y = this.getHeight() - controller.getScaleDiv2();
+
+				// Distance
+				xDist = x - tempCps.getPosition().x;
+				yDist = y - tempCps.getPosition().y;
+
+				tempCps.setPosition(x, y); // Drag Position
+				// ToolTipText Position and name
+				toolTip = true;
+				toolTipText = tempCps.getName() + ", " + tempCps.getId();
+				toolTipPos.x = tempCps.getPosition().x
+						- controller.getScaleDiv2();
+				toolTipPos.y = tempCps.getPosition().y
+						+ controller.getScaleDiv2();
+
+				// All Selected Objects
+				for (AbstractCpsObject cps : model.getSelectedCpsObjects()) {
+					if (cps != tempCps) {
+						x = (int) (cps.getPosition().x + xDist);
+						y = (int) (cps.getPosition().y + yDist);
+
+						// Make sure its in bounds
+						if (x <= controller.getScaleDiv2())
+							x = controller.getScaleDiv2();
+						else if (x > this.getWidth()
+								- controller.getScaleDiv2())
+							x = this.getWidth() - controller.getScaleDiv2();
+						if (y <= controller.getScaleDiv2())
+							y = controller.getScaleDiv2();
+						else if (y > this.getHeight()
+								- controller.getScaleDiv2())
+							y = this.getHeight() - controller.getScaleDiv2();
+
+						cps.setPosition(x, y);
+					}
+				}
+				repaint();
+			} catch (Exception eex) {
+			}
+		}
+
+		// Mark Objects
+		if (doMark) {
+			tempSelected.clear();
+			for (AbstractCpsObject cps : model.getObjectsOnCanvas()) {
+				int x1 = sx, x2 = x, y1 = sy, y2 = y;
+
+				if (sx >= x) {
+					x1 = x;
+					x2 = sx;
+				}
+				if (sy >= y) {
+					y1 = y;
+					y2 = sy;
+				}
+				if (x1 <= cps.getPosition().x + model.getScaleDiv2()
+						&& y1 <= cps.getPosition().y + model.getScaleDiv2()
+						&& x2 >= cps.getPosition().x
+						&& y2 >= cps.getPosition().y) {
+					tempSelected.add(cps);
+
+				}
+			}
+		}
+
+		repaint();
+
+	}
+
+	@Override
+	public void mouseMoved(MouseEvent e) {
+		x = e.getX();
+		y = e.getY();
+
+		// Everything for the tooltip :)
+		boolean on = false;
+		for (AbstractCpsObject cps : model.getObjectsOnCanvas()) {
+			cx = cps.getPosition().x - controller.getScaleDiv2();
+			cy = cps.getPosition().y - controller.getScaleDiv2();
+
+			on = setToolTipInfoAndPosition(on, cps);
+		}
+		toolTip = on;
+		repaint();
+	}
+
+	/**
+	 * Draws or Deletes an Edge.
+	 */
+	void drawDeleteEdge() {
+		if (getMousePosition() != null) {
+			boolean node = true;
+			boolean newEdge = true;
+			boolean onEdge = true;
+			boolean deleteNode = false;
+			CpsEdge e = null;
+
+			for (AbstractCpsObject cps : model.getObjectsOnCanvas()) {
+				cx = cps.getPosition().x - controller.getScaleDiv2();
+				cy = cps.getPosition().y - controller.getScaleDiv2();
+				if (x - controller.getScale() <= cx
+						&& y - controller.getScale() <= cy && x >= cx
+						&& y >= cy && cps != tempCps) {
+					node = false;
+					onEdge = false;
+					for (CpsEdge p : tempCps.getConnections()) {
+						if ((p.getA() == tempCps && p.getB() == cps)
+								|| (p.getB() == tempCps && p.getA() == cps)) {
+							newEdge = false;
+							e = p;
+						}
+					}
+					if (!newEdge) {
+						controller.removeEdgesOnCanvas(e);
+						// Node ohne Edge?
+						if (e.getA().getClass() == CpsNode.class
+								&& e.getA().getConnections().isEmpty()) {
+							tempCps = e.getA();
+							deleteNode = true;
+						}
+						if (e.getB().getClass() == CpsNode.class
+								&& e.getB().getConnections().isEmpty()) {
+							deleteNode = true;
+						}
+					} else {
+						e = new CpsEdge(cps, tempCps, model.getMaxCapacity());
+						controller.addEdgeOnCanvas(e);
+					}
+				}
+			}
+			// Edge auf eine Edge gezogen?
+			if (onEdge) {
+				CpsEdge p = mousePositionOnEdge(x, y);
+				if (p != null) {
+					CpsEdge e1;
+					CpsEdge e2;
+
+					node = false;
+
+					CpsNode n = new CpsNode("Node");
+
+					n.setPosition(x, y);
+					controller.addObjectCanvas(n);
+
+					AbstractCpsObject r, k;
+					r = p.getA();
+					k = p.getB();
+
+					e = new CpsEdge(n, tempCps, model.getMaxCapacity());
+
+					e1 = new CpsEdge(n, r, model.getMaxCapacity());
+
+					e2 = new CpsEdge(n, k, model.getMaxCapacity());
+
+					controller.removeEdgesOnCanvas(p);
+					controller.addEdgeOnCanvas(e);
+					controller.addEdgeOnCanvas(e1);
+					controller.addEdgeOnCanvas(e2);
+				}
+			}
+
+			// ins leere Gedragged
+			if (node) {
+				CpsNode n = new CpsNode("Node");
+
+				n.setPosition(x, y);
+				controller.addObjectCanvas(n);
+
+				e = new CpsEdge(n, tempCps, model.getMaxCapacity());
+
+				controller.addEdgeOnCanvas(e);
+			}
+
+			// Wenn ein Node ohne Connections da ist
+			if (deleteNode) {
+				controller.delCanvasObject(tempCps, true);
+				tempCps = null;
+			}
+		}
+	}
+
+	/**
+	 * Checks if the mouse is on an Edge.
+	 *
+	 * @param x
+	 *            Position of the Mouse
+	 * @param y
+	 *            Position of the Mouse
+	 * @return CpsEdge the Mouse is on, null if the mouse is not on an Edge
+	 */
+	private CpsEdge mousePositionOnEdge(int x, int y) {
+		x += controller.getScaleDiv2();
+		y += controller.getScaleDiv2();
+		for (CpsEdge p : model.getEdgesOnCanvas()) {
+			Line2D l = new Line2D.Float(p.getA().getPosition().x, p.getA()
+					.getPosition().y, p.getB().getPosition().x, p.getB()
+					.getPosition().y);
+
+			int[] positions = determineMousePositionOnEdge(p);
+			int lx = positions[0];
+			int ly = positions[1];
+			int hx = positions[2];
+			int hy = positions[3];
+
+			// distance from a point to a line and between both Objects
+			if (l.ptLineDistSq(x - model.getScaleDiv2(),
+					y - model.getScaleDiv2()) < 20
+					&& x > lx && x < hx && y > ly && y < hy) {
+				return p;
+			}
+		}
+		return null;
+	}
+
+	void updateLanguages() {
+		itemCut.setText(Languages.getLanguage()[95]);
+		itemCopy.setText(Languages.getLanguage()[96]);
+		itemPaste.setText(Languages.getLanguage()[97]);
+		itemDelete.setText(Languages.getLanguage()[98]);
+		itemGroup.setText(Languages.getLanguage()[99]);
+		itemUngroup.setText(Languages.getLanguage()[100]);
+		itemTrack.setText(Languages.getLanguage()[101]);
+		itemUntrack.setText(Languages.getLanguage()[102]);
+	}
+
+	/**
+	 * Set if Information should be shown.
+	 *
+	 * @param connection
+	 *            boolean for conecction
+	 * @param object
+	 *            boolean for objects
+	 * @param nodeOfnode
+	 */
+	void setShowedInformation(boolean connection, boolean object,
+			boolean border, boolean nodeOfnode) {
+		showedInformation[0] = connection;
+		showedInformation[1] = object;
+		showedInformation[3] = border;
+		showedInformation[4] = nodeOfnode;
+	}
+
+	/**
+	 * Returns if Information should be shown.
+	 *
+	 * @return Array of boolean [0] = connection, [1] = objects
+	 */
+	boolean[] getShowedInformation() {
+		return showedInformation;
+	}
+
+	/**
+	 * set toolTip
+	 *
+	 * @param bool
+	 */
+	void setToolTip(boolean bool) {
+		this.toolTip = bool;
+	}
+
+	/**
+	 * Set the Mouse
+	 *
+	 * @param x
+	 * @param y
+	 */
+	void setXY(int x, int y) {
+		this.x = x;
+		this.y = y;
+	}
 
 }