Browse Source

Merge branch 'master' of https://git.tk.informatik.tu-darmstadt.de/carlos.garcia/praktikum-holons

Teh-Hai Julian Zheng 7 years ago
parent
commit
6b9a922ec1

+ 16 - 13
src/classes/HolonSwitch.java

@@ -74,31 +74,33 @@ public class HolonSwitch extends AbstractCpsObject {
 	public HolonSwitch(AbstractCpsObject obj) {
 		super(obj);
 		super.setName(obj.getName());
-		setManualState(((HolonSwitch)obj).getActiveManual());
+		setManualState(((HolonSwitch) obj).getActiveManual());
 		setAutoState(true);
 		setActiveAt(true);
 		for (int i = 0; i < activeAt.length; i++) {
-			activeAt[i] = ((HolonSwitch)obj).getActiveAt()[i];
+			activeAt[i] = ((HolonSwitch) obj).getActiveAt()[i];
 		}
 		setGraphPoints(new LinkedList<Point>());
-		for (Point p :((HolonSwitch)obj).getGraphPoints()) {
-			this.graphPoints.add(new Point((int)p.getX(), (int)p.getY()));
+		for (Point p : ((HolonSwitch) obj).getGraphPoints()) {
+			this.graphPoints.add(new Point((int) p.getX(), (int) p.getY()));
 		}
-		setManualMode(((HolonSwitch)obj).getManualMode());
+		setManualMode(((HolonSwitch) obj).getManualMode());
 	}
 
 	/**
 	 * Calculates the state of the Switch.
 	 */
 	public void switchState() {
-		if (manualMode) {
-			if (this.manualActive == true) {
-				setImage("/Images/switch-off.png");
-			} else {
-				setImage("/Images/switch-on.png");
-			}
-			this.manualActive = !manualActive;
+		if (!manualMode) {
+			setManualMode(true);
+		}
+		if (this.manualActive == true) {
+			setImage("/Images/switch-off.png");
+		} else {
+			setImage("/Images/switch-on.png");
 		}
+		this.manualActive = !manualActive;
+
 	}
 
 	/**
@@ -225,7 +227,8 @@ public class HolonSwitch extends AbstractCpsObject {
 	/**
 	 * Set the overall value of the Switch (manual mode).
 	 * 
-	 * @param mode the mode (boolean)
+	 * @param mode
+	 *            the mode (boolean)
 	 */
 	public void setManualMode(boolean mode) {
 		manualMode = mode;

+ 92 - 0
src/org/eclipse/wb/swing/FocusTraversalOnArray.java

@@ -0,0 +1,92 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Google, Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Google, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wb.swing;
+
+import java.awt.Component;
+import java.awt.Container;
+import java.awt.FocusTraversalPolicy;
+
+/**
+ * Cyclic focus traversal policy based on array of components.
+ * <p>
+ * This class may be freely distributed as part of any application or plugin.
+ * 
+ * @author scheglov_ke
+ */
+public class FocusTraversalOnArray extends FocusTraversalPolicy {
+	private final Component m_Components[];
+	////////////////////////////////////////////////////////////////////////////
+	//
+	// Constructor
+	//
+	////////////////////////////////////////////////////////////////////////////
+	public FocusTraversalOnArray(Component components[]) {
+		m_Components = components;
+	}
+	////////////////////////////////////////////////////////////////////////////
+	//
+	// Utilities
+	//
+	////////////////////////////////////////////////////////////////////////////
+	private int indexCycle(int index, int delta) {
+		int size = m_Components.length;
+		int next = (index + delta + size) % size;
+		return next;
+	}
+	private Component cycle(Component currentComponent, int delta) {
+		int index = -1;
+		loop : for (int i = 0; i < m_Components.length; i++) {
+			Component component = m_Components[i];
+			for (Component c = currentComponent; c != null; c = c.getParent()) {
+				if (component == c) {
+					index = i;
+					break loop;
+				}
+			}
+		}
+		// try to find enabled component in "delta" direction
+		int initialIndex = index;
+		while (true) {
+			int newIndex = indexCycle(index, delta);
+			if (newIndex == initialIndex) {
+				break;
+			}
+			index = newIndex;
+			//
+			Component component = m_Components[newIndex];
+			if (component.isEnabled() && component.isVisible() && component.isFocusable()) {
+				return component;
+			}
+		}
+		// not found
+		return currentComponent;
+	}
+	////////////////////////////////////////////////////////////////////////////
+	//
+	// FocusTraversalPolicy
+	//
+	////////////////////////////////////////////////////////////////////////////
+	public Component getComponentAfter(Container container, Component component) {
+		return cycle(component, 1);
+	}
+	public Component getComponentBefore(Container container, Component component) {
+		return cycle(component, -1);
+	}
+	public Component getFirstComponent(Container container) {
+		return m_Components[0];
+	}
+	public Component getLastComponent(Container container) {
+		return m_Components[m_Components.length - 1];
+	}
+	public Component getDefaultComponent(Container container) {
+		return getFirstComponent(container);
+	}
+}

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

@@ -41,6 +41,7 @@ public class Control {
 	private final StatsController statsController;
 	private final NodeController nodeController;
 	private final ClipboardController clipboardController;
+	private final HolonCanvasController holonCanvasController;
 	private String autoPath = "";
 
 	/**
@@ -67,6 +68,7 @@ public class Control {
 		this.statsController = new StatsController(model);
 		this.clipboardController = new ClipboardController(model, storeController, loadController, canvasController,
 				objectController, nodeController, multiPurposeController);
+		this.holonCanvasController = new HolonCanvasController(model);
 
 		autoPath = System.getProperty("user.home") + "/HolonGUI/Autosave/";
 		File dest = new File(autoPath);
@@ -875,4 +877,24 @@ public class Control {
 		clipboardController.getObjectsInDepth();
 	}
 
+	public float getTotalProduction(ArrayList<AbstractCpsObject> arrayList) {
+		return holonCanvasController.getTotalProduction(arrayList);
+	}
+
+	public float getTotalConsumption(ArrayList<AbstractCpsObject> arrayList) {
+		return holonCanvasController.getTotalConsumption(arrayList);
+	}
+
+	public int getTotalElements(ArrayList<AbstractCpsObject> arrayList) {
+		return holonCanvasController.getTotalElements(arrayList) ;
+	}
+
+	public int getTotalProducers(ArrayList<AbstractCpsObject> arrayList) {
+		return holonCanvasController.getTotalProducers(arrayList);
+	}
+
+	public int getActiveElements(ArrayList<AbstractCpsObject> arrayList) {
+		return holonCanvasController.getActiveElements(arrayList);
+	}
+
 }

+ 263 - 0
src/ui/controller/HolonCanvasController.java

@@ -1,5 +1,268 @@
 package ui.controller;
 
+import java.awt.Dimension;
+import java.util.ArrayList;
+
+import classes.AbstractCpsObject;
+import classes.Constants;
+import classes.CpsUpperNode;
+import classes.HolonBody;
+import classes.HolonElement;
+import classes.HolonObject;
+import classes.SubNet;
+import classes.Vector2d;
+import ui.model.Model;
+
 public class HolonCanvasController {
 
+	// Ball objects
+	private ArrayList<HolonBody> bodies = new ArrayList<>();
+	private int subCount;
+	private Dimension center;
+	private Model model;
+	private ArrayList<HolonBody> sortedSize = new ArrayList<>();
+	private ArrayList<HolonBody> sortedDist = new ArrayList<>();
+	private int toDrag;
+	private boolean beingDragged;
+
+	/**
+	 * Constructor.
+	 * 
+	 * @param model
+	 *            the Model
+	 * @param mp
+	 *            the MultipurposeController
+	 */
+	public HolonCanvasController(Model model) {
+		this.model = model;
+	}
+
+	// sort the HolonBodys after size
+	public void rearrangeAfterSize() {
+		int j = 0;
+		sortedSize.addAll(bodies);
+		insertionSizeSort(sortedSize);
+		sortedDist.addAll(bodies);
+
+		ArrayList<Vector2d> pos = insertionDistSort(sortedDist);
+		for (int i = 0; i < subCount; i++) {
+			for (j = 0; j < subCount; j++) {
+				if (sortedSize.get(subCount - 1 - i).getId() == bodies.get(j).getId()) {
+					bodies.get(j).position = pos.get(i);
+					break;
+				}
+			}
+		}
+	}
+
+	// updates the bodies according to the changes of subnets
+	public void addNewBodies(int subCount, ArrayList<SubNet> subnets, Dimension center, int HolonBodyScale) {
+		this.subCount = subCount;
+		this.center = center;
+		// find correct color for existing HolonBodys
+		ArrayList<HolonBody> newBodies = new ArrayList<>();
+		for (int i = 0; i < subCount; i++) {
+			for (int j = 0; j < bodies.size(); j++) {
+				if (model.getSubNetColors().get(i) == bodies.get(j).getColor()) {
+					bodies.get(j).setRadius((subnets.get(i).getObjects().size() * 5 + 10) * HolonBodyScale / 100);
+					bodies.get(j).setMass((float) Math.pow((subnets.get(i).getObjects().size() + 1) * 5, 3));
+					newBodies.add(bodies.get(j));
+					newBodies.get(i).setId(i);
+					break;
+				}
+			}
+		}
+
+		bodies = newBodies;
+		// adding new HolonBodys
+		for (int i = bodies.size(); i < subCount; i++) {
+			float radius = (subnets.get(i).getObjects().size() * 5 + 10) * HolonBodyScale / 100;
+			HolonBody temp = new HolonBody((float) (center.width + Math.pow(-1, i)), center.height + 1, radius,
+					(float) Math.pow((subnets.get(i).getObjects().size() + 1) * 5, 3), model.getSubNetColors().get(i));
+			temp.setId(i);
+			bodies.add(temp);
+		}
+	}
+
+	public int getActiveElements(ArrayList<AbstractCpsObject> objects) {
+		int val = 0;
+		for (AbstractCpsObject obj : objects) {
+			if (obj instanceof HolonObject) {
+				for (HolonElement ele : ((HolonObject) obj).getElements()) {
+					if (ele.getActive()) {
+						val += 1;
+					}
+				}
+			} else if (obj instanceof CpsUpperNode) {
+				val += getTotalProduction(((CpsUpperNode) obj).getNodes());
+			}
+		}
+		return val;
+	}
+
+	public int getTotalProducers(ArrayList<AbstractCpsObject> objects) {
+		float val = 0;
+		int prod = 0;
+		int tStep = model.getCurIteration();
+		for (AbstractCpsObject obj : objects) {
+			if (obj instanceof HolonObject) {
+				for (HolonElement ele : ((HolonObject) obj).getElements()) {
+					if (ele.getEnergyAt()[tStep] > 0 && ele.getActive()) {
+						val += ele.getEnergyAt()[tStep] * ele.getAmount();
+					}
+				}
+				if (val > 0)
+					prod += 1;
+			} else if (obj instanceof CpsUpperNode) {
+				val += getTotalProduction(((CpsUpperNode) obj).getNodes());
+			}
+		}
+		return prod;
+	}
+
+	public int getTotalElements(ArrayList<AbstractCpsObject> objects) {
+		int val = 0;
+		for (AbstractCpsObject obj : objects) {
+			if (obj instanceof HolonObject) {
+				val += ((HolonObject) obj).getElements().size();
+			} else if (obj instanceof CpsUpperNode) {
+				val += getTotalConsumption(((CpsUpperNode) obj).getNodes());
+			}
+		}
+		return val;
+	}
+
+	public float getTotalConsumption(ArrayList<AbstractCpsObject> objects) {
+		float val = 0;
+		int tStep = model.getCurIteration();
+		for (AbstractCpsObject obj : objects) {
+			if (obj instanceof HolonObject) {
+				for (HolonElement ele : ((HolonObject) obj).getElements()) {
+					if (ele.getEnergyAt()[tStep] < 0 && ele.getActive()) {
+						val += ele.getEnergyAt()[tStep] * ele.getAmount();
+					}
+				}
+			} else if (obj instanceof CpsUpperNode) {
+				val += getTotalConsumption(((CpsUpperNode) obj).getNodes());
+			}
+		}
+		return val;
+	}
+
+	public float getTotalProduction(ArrayList<AbstractCpsObject> objects) {
+		float val = 0;
+		int tStep = model.getCurIteration();
+		for (AbstractCpsObject obj : objects) {
+			if (obj instanceof HolonObject) {
+				for (HolonElement ele : ((HolonObject) obj).getElements()) {
+					if (ele.getEnergyAt()[tStep] > 0 && ele.getActive()) {
+						val += ele.getEnergyAt()[tStep] * ele.getAmount();
+					}
+				}
+			} else if (obj instanceof CpsUpperNode) {
+				val += getTotalProduction(((CpsUpperNode) obj).getNodes());
+			}
+		}
+		return val;
+	}
+
+	public void updateBodies(float elapsedSeconds) {
+		// step the position of movable objects based off their velocity/gravity
+		// and elapsedTime
+		for (int i = 0; i < subCount; i++) {
+			if (toDrag != bodies.get(i).getId() || !beingDragged) {
+				bodies.get(i).position.setX(
+						(float) (bodies.get(i).position.getX() + (bodies.get(i).velocity.getX() * (elapsedSeconds))
+								- ((bodies.get(i).position.getX() - center.getWidth()) / (50 + subCount))));
+				bodies.get(i).position.setY(
+						(float) (bodies.get(i).position.getY() + (bodies.get(i).velocity.getY() * (elapsedSeconds))
+								- ((bodies.get(i).position.getY() - center.getHeight()) / (50 + subCount))));
+
+				if (Math.abs(bodies.get(i).velocity.getX()) < Constants.epsilon)
+					bodies.get(i).velocity.setX(0);
+				if (Math.abs(bodies.get(i).velocity.getY()) < Constants.epsilon)
+					bodies.get(i).velocity.setY(0);
+			}
+		}
+		checkCollisions();
+	}
+
+	// Insertion sort for Sweep and Prune
+	public void insertionSort(ArrayList<HolonBody> a) {
+		for (int p = 1; p < subCount; p++) {
+			Comparable<HolonBody> tmp = a.get(p);
+			int j = p;
+
+			for (; j > 0 && tmp.compareTo(a.get(j - 1)) < 0; j--)
+				a.set(j, a.get(j - 1));
+
+			a.set(j, (HolonBody) tmp);
+		}
+	}
+
+	// Insertion sort for subnet size
+	private void insertionSizeSort(ArrayList<HolonBody> a) {
+		for (int p = 1; p < subCount; p++) {
+			HolonBody tmp = a.get(p);
+			int j = p;
+
+			for (; j > 0 && tmp.compareSizeTo(a.get(j - 1)) < 0; j--)
+				a.set(j, a.get(j - 1));
+
+			a.set(j, (HolonBody) tmp);
+		}
+	}
+
+	// Insertion sort for HolonBody distance
+	private ArrayList<Vector2d> insertionDistSort(ArrayList<HolonBody> a) {
+		ArrayList<Vector2d> pos = new ArrayList<>();
+		for (int p = 1; p < subCount; p++) {
+			HolonBody tmp = a.get(p);
+			int j = p;
+
+			for (; j > 0 && tmp.compareDistTo(a.get(j - 1), center) < 0; j--)
+				a.set(j, a.get(j - 1));
+
+			a.set(j, (HolonBody) tmp);
+		}
+		for (int i = 0; i < subCount; i++)
+			pos.add(a.get(i).position);
+		return pos;
+	}
+
+	public void checkCollisions() {
+		insertionSort(bodies);
+
+		for (int i = 0; i < subCount; i++) {
+			// Ball to Ball collision
+			for (int j = i + 1; j < subCount; j++) {
+				if ((bodies.get(i).position.getX() + bodies.get(i).getRadius()) < (bodies.get(j).position.getX()
+						- bodies.get(j).getRadius()))
+					break;
+
+				if ((bodies.get(i).position.getY() + bodies.get(i).getRadius()) < (bodies.get(j).position.getY()
+						- bodies.get(j).getRadius())
+						|| (bodies.get(j).position.getY() + bodies.get(j).getRadius()) < (bodies.get(i).position.getY()
+								- bodies.get(i).getRadius()))
+					continue;
+
+				bodies.get(i).resolveCollision(bodies.get(j));
+
+			}
+		}
+
+	}
+
+	public ArrayList<HolonBody> getBodies() {
+		return bodies;
+	}
+
+	public void setDrag(boolean beingDragged) {
+		this.beingDragged = beingDragged;
+	}
+
+	public void setBodyToDrag(int i) {
+		this.toDrag = i;
+	}
+
 }

+ 6 - 92
src/ui/controller/UpdateController.java

@@ -1,6 +1,5 @@
 package ui.controller;
 
-import java.awt.event.MouseEvent;
 import java.util.ArrayList;
 import java.util.HashMap;
 
@@ -11,13 +10,11 @@ import classes.HolonElement;
 import classes.HolonObject;
 import classes.HolonSwitch;
 import classes.SubNet;
+import ui.model.Model;
 import ui.view.DefaulTable;
 import ui.view.Languages;
 import ui.view.PropertyTable;
-import ui.view.UnitGraph;
 import ui.view.UpperNodeCanvas;
-import ui.model.*;
-import ui.controller.*;
 
 /**
  * This class is for all update methods and more ;)
@@ -373,104 +370,21 @@ public class UpdateController {
 				Object[] tempSwi = { "Nr. of Switches", sub.getSwitches().size() };
 				model.getPropertyTable().addRow(tempSwi);
 				Object[] tempProd = { "Total Production",
-						"" + getTotalProduction(new ArrayList<AbstractCpsObject>(sub.getObjects())) };
+						"" + controller.getTotalProduction(new ArrayList<AbstractCpsObject>(sub.getObjects())) };
 				model.getPropertyTable().addRow(tempProd);
 				Object[] tempCons = { "Total Consumption",
-						"" + getTotalConsumption(new ArrayList<AbstractCpsObject>(sub.getObjects())) };
+						"" + controller.getTotalConsumption(new ArrayList<AbstractCpsObject>(sub.getObjects())) };
 				model.getPropertyTable().addRow(tempCons);
 				Object[] tempEle = { "Nr. of Elements",
-						"" + getTotalElements(new ArrayList<AbstractCpsObject>(sub.getObjects())) };
+						"" + controller.getTotalElements(new ArrayList<AbstractCpsObject>(sub.getObjects())) };
 				model.getPropertyTable().addRow(tempEle);
 				Object[] tempProds = { "Nr. of Producers",
-						"" + getTotalProducers(new ArrayList<AbstractCpsObject>(sub.getObjects())) };
+						"" + controller.getTotalProducers(new ArrayList<AbstractCpsObject>(sub.getObjects())) };
 				model.getPropertyTable().addRow(tempProds);
 				Object[] tempAct = { "Nr. of active Elements",
-						"" + getActiveElements(new ArrayList<AbstractCpsObject>(sub.getObjects())) };
+						"" + controller.getActiveElements(new ArrayList<AbstractCpsObject>(sub.getObjects())) };
 				model.getPropertyTable().addRow(tempAct);
 			}
 		}
 	}
-
-	private int getActiveElements(ArrayList<AbstractCpsObject> objects) {
-		int val = 0;
-		for (AbstractCpsObject obj : objects) {
-			if (obj instanceof HolonObject) {
-				for (HolonElement ele : ((HolonObject) obj).getElements()) {
-					if (ele.getActive()) {
-						val += 1;
-					}
-				}
-			} else if (obj instanceof CpsUpperNode) {
-				val += getTotalProduction(((CpsUpperNode) obj).getNodes());
-			}
-		}
-		return val;
-	}
-
-	private int getTotalProducers(ArrayList<AbstractCpsObject> objects) {
-		float val = 0;
-		int prod = 0;
-		int tStep = model.getCurIteration();
-		for (AbstractCpsObject obj : objects) {
-			if (obj instanceof HolonObject) {
-				for (HolonElement ele : ((HolonObject) obj).getElements()) {
-					if (ele.getEnergyAt()[tStep] > 0 && ele.getActive()) {
-						val += ele.getEnergyAt()[tStep] * ele.getAmount();
-					}
-				}
-				if (val > 0)
-					prod += 1;
-			} else if (obj instanceof CpsUpperNode) {
-				val += getTotalProduction(((CpsUpperNode) obj).getNodes());
-			}
-		}
-		return prod;
-	}
-
-	private int getTotalElements(ArrayList<AbstractCpsObject> objects) {
-		int val = 0;
-		for (AbstractCpsObject obj : objects) {
-			if (obj instanceof HolonObject) {
-				val += ((HolonObject) obj).getElements().size();
-			} else if (obj instanceof CpsUpperNode) {
-				val += getTotalConsumption(((CpsUpperNode) obj).getNodes());
-			}
-		}
-		return val;
-	}
-
-	private float getTotalConsumption(ArrayList<AbstractCpsObject> objects) {
-		float val = 0;
-		int tStep = model.getCurIteration();
-		for (AbstractCpsObject obj : objects) {
-			if (obj instanceof HolonObject) {
-				for (HolonElement ele : ((HolonObject) obj).getElements()) {
-					if (ele.getEnergyAt()[tStep] < 0 && ele.getActive()) {
-						val += ele.getEnergyAt()[tStep] * ele.getAmount();
-					}
-				}
-			} else if (obj instanceof CpsUpperNode) {
-				val += getTotalConsumption(((CpsUpperNode) obj).getNodes());
-			}
-		}
-		return val;
-	}
-
-	private float getTotalProduction(ArrayList<AbstractCpsObject> arrayList) {
-		float val = 0;
-		int tStep = model.getCurIteration();
-		for (AbstractCpsObject obj : arrayList) {
-			if (obj instanceof HolonObject) {
-				for (HolonElement ele : ((HolonObject) obj).getElements()) {
-					if (ele.getEnergyAt()[tStep] > 0 && ele.getActive()) {
-						val += ele.getEnergyAt()[tStep] * ele.getAmount();
-					}
-				}
-			} else if (obj instanceof CpsUpperNode) {
-				val += getTotalProduction(((CpsUpperNode) obj).getNodes());
-			}
-		}
-		return val;
-	}
-
 }

+ 93 - 0
src/ui/view/BackgroundPopUp.java

@@ -0,0 +1,93 @@
+package ui.view;
+
+import javax.swing.JDialog;
+import javax.swing.JFileChooser;
+import javax.swing.JFrame;
+import javax.swing.JPanel;
+import javax.swing.JTextField;
+import javax.swing.filechooser.FileNameExtensionFilter;
+import javax.swing.ImageIcon;
+import javax.swing.JButton;
+import org.eclipse.wb.swing.FocusTraversalOnArray;
+
+import javafx.scene.image.Image;
+import javafx.stage.FileChooser;
+
+import java.awt.Component;
+import java.awt.Window;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.io.File;
+import java.awt.BorderLayout;
+import javax.swing.JLabel;
+import javax.swing.JRadioButton;
+import javax.swing.BoxLayout;
+import javax.swing.SwingConstants;
+import java.awt.FlowLayout;
+import java.awt.Choice;
+
+/**
+ * Popup for setting the Background Image for the current View.
+ **/
+public class BackgroundPopUp extends JDialog {
+
+	/**
+	 * 
+	 */
+	private static final long serialVersionUID = 1L;
+	private final JTextField textPath = new JTextField("");
+	private final JButton btnBrowse = new JButton("Browse");
+	private JPanel panelImageRadio = new JPanel();
+
+	private String path = "";
+	private final JPanel panelBrowse = new JPanel();
+	private final JPanel panelOK = new JPanel();
+	private final JButton btnOK = new JButton("OK");
+	private final JLabel lblImage = new JLabel();
+
+	private double imgScale = 1;
+
+	public BackgroundPopUp() {
+		super((java.awt.Frame) null, true);
+		this.setTitle("Set View Background");
+		setBounds(100, 100, 400, 250);
+
+		getContentPane().add(panelImageRadio, BorderLayout.CENTER);
+		panelImageRadio.setLayout(new FlowLayout(FlowLayout.CENTER, 5, 5));
+		lblImage.setHorizontalAlignment(SwingConstants.RIGHT);
+
+		panelImageRadio.add(lblImage);
+		getContentPane().add(panelBrowse, BorderLayout.NORTH);
+		panelBrowse.add(btnBrowse);
+
+		// Browse Row Functions
+		btnBrowse.addActionListener(new ActionListener() {
+			@Override
+			public void actionPerformed(ActionEvent e) {
+				JFileChooser fileChooser = new JFileChooser();
+				FileNameExtensionFilter filter = new FileNameExtensionFilter("png, jpg or jpeg", "png", "jpg", "jpeg");
+				fileChooser.setFileFilter(filter);
+				if (fileChooser.showOpenDialog(null) == JFileChooser.APPROVE_OPTION) {
+					textPath.setText(fileChooser.getSelectedFile().getPath());
+					ImageIcon icon = new ImageIcon(textPath.getText());
+					imgScale = Math.max(icon.getIconWidth(), icon.getIconHeight()) / 200;
+					lblImage.setIcon(new ImageIcon(new ImageIcon(textPath.getText()).getImage().getScaledInstance(
+							(int) (icon.getIconWidth() / imgScale), (int) (icon.getIconHeight() / imgScale),
+							java.awt.Image.SCALE_SMOOTH)));
+				}
+			}
+		});
+
+		textPath.setEditable(false);
+
+		panelBrowse.add(textPath);
+		textPath.setColumns(20);
+		panelImageRadio.setFocusTraversalPolicy(new FocusTraversalOnArray(new Component[] { btnBrowse, textPath }));
+
+		getContentPane().add(panelOK, BorderLayout.SOUTH);
+
+		panelOK.add(btnOK);
+
+	}
+
+}

+ 15 - 11
src/ui/view/GUI.java

@@ -12,20 +12,14 @@ import java.awt.event.ActionEvent;
 import java.awt.event.ActionListener;
 import java.awt.event.ComponentAdapter;
 import java.awt.event.ComponentEvent;
-import java.awt.event.FocusEvent;
-import java.awt.event.FocusListener;
 import java.awt.event.KeyEvent;
 import java.awt.event.MouseAdapter;
 import java.awt.event.MouseEvent;
-import java.awt.event.MouseListener;
 import java.beans.PropertyChangeEvent;
 import java.beans.PropertyChangeListener;
-import java.beans.PropertyVetoException;
-import java.beans.VetoableChangeListener;
 import java.io.File;
 import java.io.IOException;
 import java.util.ArrayList;
-import java.util.HashMap;
 import java.util.Timer;
 import java.util.TimerTask;
 
@@ -39,7 +33,6 @@ import javax.swing.JButton;
 import javax.swing.JComboBox;
 import javax.swing.JComponent;
 import javax.swing.JDialog;
-import javax.swing.JEditorPane;
 import javax.swing.JFileChooser;
 import javax.swing.JFrame;
 import javax.swing.JLabel;
@@ -72,7 +65,6 @@ import javax.swing.tree.TreeCellRenderer;
 
 import classes.AbstractCpsObject;
 import classes.Category;
-import classes.CpsEdge;
 import classes.CpsUpperNode;
 import classes.HolonElement;
 import classes.HolonObject;
@@ -80,13 +72,10 @@ import classes.HolonSwitch;
 import classes.HolonTransformer;
 import classes.IdCounter;
 import classes.IdCounterElem;
-import classes.TrackedDataSet;
 import interfaces.CategoryListener;
-import sun.awt.RepaintArea;
 import ui.controller.Control;
 import ui.controller.UpdateController;
 import ui.model.Model;
-import java.awt.Label;
 
 /**
  * Graphical User Interface.
@@ -116,6 +105,7 @@ public class GUI<E> implements CategoryListener {
 	private final JMenuItem mntmSave = new JMenuItem("Save");
 	private final JMenuItem aboutUs = new JMenuItem("About Us");
 	private final JMenuItem canvasSize = new JMenuItem("View Size");
+	private final JMenuItem background = new JMenuItem("Background Image");
 	private final JSplitPane splitPane = new JSplitPane();
 	private final JSplitPane splitPane1 = new JSplitPane();
 	private final JSplitPane splitPaneCanvasConsole = new JSplitPane(JSplitPane.VERTICAL_SPLIT);
@@ -680,6 +670,20 @@ public class GUI<E> implements CategoryListener {
 				canvas.repaint();
 			}
 		});
+		
+		mnNewMenuView.add(canvasSize);
+		
+		mnNewMenuView.add(background);
+		background.addActionListener(new ActionListener() {
+			
+			@Override
+			public void actionPerformed(ActionEvent e) {
+				BackgroundPopUp backgroundDialog = new BackgroundPopUp();
+				backgroundDialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
+				backgroundDialog.setVisible(true);
+			}
+		});
+		
 		splitPane3.setRightComponent(sizeSlider);
 
 		splitPane3.setLeftComponent(lblImageSize);

+ 21 - 248
src/ui/view/HolonCanvas.java

@@ -31,6 +31,7 @@ import classes.HolonObject;
 import classes.SubNet;
 import classes.Vector2d;
 import ui.controller.Control;
+import ui.controller.HolonCanvasController;
 import ui.model.Model;
 
 public class HolonCanvas extends JPanel implements MouseWheelListener, MouseListener, MouseMotionListener {
@@ -57,27 +58,25 @@ public class HolonCanvas extends JPanel implements MouseWheelListener, MouseList
 	private int frameCount = 0;
 	private Dimension center;
 	private ArrayList<SubNet> subnets;
+	private HolonCanvasController hCController;
 
 	private Control controller;
 	private Model model;
-	private int maxX;
-	private int maxY;
 	private JComboBox<String> combo = new JComboBox<>();
 	private int comboChoice = 0;
 	private String info;
 	private int bodyNr;
 	private final JLabel lblBodyInfo = new JLabel("Holon Info:");
 	private JCheckBox chckbxSort = new JCheckBox("sort by size");
-	private ArrayList<HolonBody> sortedSize = new ArrayList<>();
-	private ArrayList<HolonBody> sortedDist = new ArrayList<>();
 	private boolean sizeChange = false;
 	private HolonBody toDrag;
-	private boolean beingDragged = false;
-
+	
 	public HolonCanvas(Model mod, Control control) {
 		// Wire up Events
 		this.controller = control;
 		this.model = mod;
+		
+		hCController = new HolonCanvasController(mod);
 
 		add(lblBodyInfo);
 		this.add(combo);
@@ -133,9 +132,7 @@ public class HolonCanvas extends JPanel implements MouseWheelListener, MouseList
 			subnets = controller.getSimManager().getSubNets();
 			subCount = subnets.size();
 			calcCenter();
-			maxX = center.width;
-			maxY = center.height;
-			addNewBodies(subCount);
+			hCController.addNewBodies(subCount,subnets, center, controller.getHolonBodyScale());
 			sizeChange = true;
 		}
 
@@ -151,9 +148,10 @@ public class HolonCanvas extends JPanel implements MouseWheelListener, MouseList
 
 		// check if HolonBodys should bes sorted after size
 		if (chckbxSort.isSelected() && sizeChange) {
-			rearrangeAfterSize();
+			hCController.rearrangeAfterSize();
+			sizeChange = false;
 		}
-		updateBodies(elapsedTime / 1000f);
+		hCController.updateBodies(elapsedTime / 1000f);
 
 		render(g);
 
@@ -167,64 +165,7 @@ public class HolonCanvas extends JPanel implements MouseWheelListener, MouseList
 		previousTime = currentTime;
 		frameCount++;
 		repaint();
-	}
-
-	// sort the HolonBodys after size
-	private void rearrangeAfterSize() {
-		sizeChange = false;
-		HolonBody tmp = null;
-		int j = 0;
-		sortedSize.addAll(bodies);
-		insertionSizeSort(sortedSize);
-		sortedDist.addAll(bodies);
-
-		ArrayList<Vector2d> pos = insertionDistSort(sortedDist);
-		for (int i = 0; i < subCount; i++) {
-			for (j = 0; j < subCount; j++) {
-				if (sortedSize.get(subCount - 1 - i).getId() == bodies.get(j).getId()) {
-					bodies.get(j).position = pos.get(i);
-					break;
-				}
-			}
-		}
-	}
-
-	// updates the bodies according to the changes of subnets
-	private void addNewBodies(int subCount) {
-		// find correct color for existing HolonBodys
-		ArrayList<HolonBody> newBodies = new ArrayList<>();
-		for (int i = 0; i < subCount; i++) {
-			for (int j = 0; j < bodies.size(); j++) {
-				if (model.getSubNetColors().get(i) == bodies.get(j).getColor()) {
-					bodies.get(j).setRadius(
-							(subnets.get(i).getObjects().size() * 5 + 10) * controller.getHolonBodyScale() / 100);
-					bodies.get(j).setMass((float) Math.pow((subnets.get(i).getObjects().size() + 1) * 5, 3));
-					newBodies.add(bodies.get(j));
-					newBodies.get(i).setId(i);
-					if (newBodies.get(i).position.getX() > maxX)
-						maxX = (int) newBodies.get(i).position.getX();
-					if (newBodies.get(i).position.getY() > maxY)
-						maxY = (int) newBodies.get(i).position.getY();
-					break;
-				}
-			}
-		}
-
-		bodies = newBodies;
-		// adding new HolonBodys
-		for (int i = bodies.size(); i < subCount; i++) {
-			float radius = (subnets.get(i).getObjects().size() * 5 + 10) * controller.getHolonBodyScale() / 100;
-			HolonBody temp = new HolonBody(maxX + 1, maxY + 1, radius,
-					(float) Math.pow((subnets.get(i).getObjects().size() + 1) * 5, 3), model.getSubNetColors().get(i));
-			temp.setId(i);
-			bodies.add(temp);
-
-			if (bodies.get(i).position.getX() > maxX)
-				maxX = (int) newBodies.get(i).position.getX();
-			if (bodies.get(i).position.getY() > maxY)
-				maxY = (int) newBodies.get(i).position.getY();
-		}
-	}
+	}	
 
 	public void render(Graphics g) {
 		this.g2 = (Graphics2D) g;
@@ -234,6 +175,7 @@ public class HolonCanvas extends JPanel implements MouseWheelListener, MouseList
 		this.g2.setColor(Color.WHITE);
 		this.g2.fillRect(0, 0, getWidth(), getHeight());
 
+		bodies = hCController.getBodies();
 		// Render Game Objects
 		for (int i = 0; i < subCount; i++) {
 			bodyNr = bodies.get(i).getId();
@@ -251,19 +193,19 @@ public class HolonCanvas extends JPanel implements MouseWheelListener, MouseList
 				info = "" + subnets.get(bodyNr).getSwitches().size();
 				break;
 			case 4:
-				info = "" + getTotalProduction(new ArrayList<AbstractCpsObject>(subnets.get(bodyNr).getObjects()));
+				info = "" + hCController.getTotalProduction(new ArrayList<AbstractCpsObject>(subnets.get(bodyNr).getObjects()));
 				break;
 			case 5:
-				info = "" + getTotalConsumption(new ArrayList<AbstractCpsObject>(subnets.get(bodyNr).getObjects()));
+				info = "" + hCController.getTotalConsumption(new ArrayList<AbstractCpsObject>(subnets.get(bodyNr).getObjects()));
 				break;
 			case 6:
-				info = "" + getTotalElements(new ArrayList<AbstractCpsObject>(subnets.get(bodyNr).getObjects()));
+				info = "" + hCController.getTotalElements(new ArrayList<AbstractCpsObject>(subnets.get(bodyNr).getObjects()));
 				break;
 			case 7:
-				info = "" + getTotalProducers(new ArrayList<AbstractCpsObject>(subnets.get(bodyNr).getObjects()));
+				info = "" + hCController.getTotalProducers(new ArrayList<AbstractCpsObject>(subnets.get(bodyNr).getObjects()));
 				break;
 			case 8:
-				info = "" + getActiveElements(new ArrayList<AbstractCpsObject>(subnets.get(bodyNr).getObjects()));
+				info = "" + hCController.getActiveElements(new ArrayList<AbstractCpsObject>(subnets.get(bodyNr).getObjects()));
 				break;
 			default:
 				info = "" + bodyNr;
@@ -275,177 +217,7 @@ public class HolonCanvas extends JPanel implements MouseWheelListener, MouseList
 		}
 	}
 
-	private int getActiveElements(ArrayList<AbstractCpsObject> objects) {
-		int val = 0;
-		for (AbstractCpsObject obj : objects) {
-			if (obj instanceof HolonObject) {
-				for (HolonElement ele : ((HolonObject) obj).getElements()) {
-					if (ele.getActive()) {
-						val += 1;
-					}
-				}
-			} else if (obj instanceof CpsUpperNode) {
-				val += getTotalProduction(((CpsUpperNode) obj).getNodes());
-			}
-		}
-		return val;
-	}
-
-	private int getTotalProducers(ArrayList<AbstractCpsObject> objects) {
-		float val = 0;
-		int prod = 0;
-		int tStep = model.getCurIteration();
-		for (AbstractCpsObject obj : objects) {
-			if (obj instanceof HolonObject) {
-				for (HolonElement ele : ((HolonObject) obj).getElements()) {
-					if (ele.getEnergyAt()[tStep] > 0 && ele.getActive()) {
-						val += ele.getEnergyAt()[tStep] * ele.getAmount();
-					}
-				}
-				if (val > 0)
-					prod += 1;
-			} else if (obj instanceof CpsUpperNode) {
-				val += getTotalProduction(((CpsUpperNode) obj).getNodes());
-			}
-		}
-		return prod;
-	}
-
-	private int getTotalElements(ArrayList<AbstractCpsObject> objects) {
-		int val = 0;
-		for (AbstractCpsObject obj : objects) {
-			if (obj instanceof HolonObject) {
-				val += ((HolonObject) obj).getElements().size();
-			} else if (obj instanceof CpsUpperNode) {
-				val += getTotalConsumption(((CpsUpperNode) obj).getNodes());
-			}
-		}
-		return val;
-	}
-
-	private float getTotalConsumption(ArrayList<AbstractCpsObject> objects) {
-		float val = 0;
-		int tStep = model.getCurIteration();
-		for (AbstractCpsObject obj : objects) {
-			if (obj instanceof HolonObject) {
-				for (HolonElement ele : ((HolonObject) obj).getElements()) {
-					if (ele.getEnergyAt()[tStep] < 0 && ele.getActive()) {
-						val += ele.getEnergyAt()[tStep] * ele.getAmount();
-					}
-				}
-			} else if (obj instanceof CpsUpperNode) {
-				val += getTotalConsumption(((CpsUpperNode) obj).getNodes());
-			}
-		}
-		return val;
-	}
-
-	private float getTotalProduction(ArrayList<AbstractCpsObject> objects) {
-		float val = 0;
-		int tStep = model.getCurIteration();
-		for (AbstractCpsObject obj : objects) {
-			if (obj instanceof HolonObject) {
-				for (HolonElement ele : ((HolonObject) obj).getElements()) {
-					if (ele.getEnergyAt()[tStep] > 0 && ele.getActive()) {
-						val += ele.getEnergyAt()[tStep] * ele.getAmount();
-					}
-				}
-			} else if (obj instanceof CpsUpperNode) {
-				val += getTotalProduction(((CpsUpperNode) obj).getNodes());
-			}
-		}
-		return val;
-	}
-
-	public void updateBodies(float elapsedSeconds) {
-
-		// step the position of movable objects based off their velocity/gravity
-		// and elapsedTime
-		calcCenter();
-		for (int i = 0; i < subCount; i++) {
-			if (!bodies.get(i).equals(toDrag) || (bodies.get(i).equals(toDrag)&& !beingDragged)) {
-				bodies.get(i).position.setX(
-						(float) (bodies.get(i).position.getX() + (bodies.get(i).velocity.getX() * (elapsedSeconds))
-								- ((bodies.get(i).position.getX() - center.getWidth()) / (50 + subCount))));
-				bodies.get(i).position.setY(
-						(float) (bodies.get(i).position.getY() + (bodies.get(i).velocity.getY() * (elapsedSeconds))
-								- ((bodies.get(i).position.getY() - center.getHeight()) / (50 + subCount))));
-
-				if (Math.abs(bodies.get(i).velocity.getX()) < Constants.epsilon)
-					bodies.get(i).velocity.setX(0);
-				if (Math.abs(bodies.get(i).velocity.getY()) < Constants.epsilon)
-					bodies.get(i).velocity.setY(0);
-			}
-		}
-		checkCollisions();
-	}
-
-	// Insertion sort for Sweep and Prune
-	public void insertionSort(ArrayList<HolonBody> a) {
-		for (int p = 1; p < subCount; p++) {
-			Comparable<HolonBody> tmp = a.get(p);
-			int j = p;
-
-			for (; j > 0 && tmp.compareTo(a.get(j - 1)) < 0; j--)
-				a.set(j, a.get(j - 1));
-
-			a.set(j, (HolonBody) tmp);
-		}
-	}
-
-	// Insertion sort for subnet size
-	private void insertionSizeSort(ArrayList<HolonBody> a) {
-		for (int p = 1; p < subCount; p++) {
-			HolonBody tmp = a.get(p);
-			int j = p;
-
-			for (; j > 0 && tmp.compareSizeTo(a.get(j - 1)) < 0; j--)
-				a.set(j, a.get(j - 1));
-
-			a.set(j, (HolonBody) tmp);
-		}
-	}
-
-	// Insertion sort for HolonBody distance
-	private ArrayList<Vector2d> insertionDistSort(ArrayList<HolonBody> a) {
-		ArrayList<Vector2d> pos = new ArrayList<>();
-		for (int p = 1; p < subCount; p++) {
-			HolonBody tmp = a.get(p);
-			int j = p;
-
-			for (; j > 0 && tmp.compareDistTo(a.get(j - 1), center) < 0; j--)
-				a.set(j, a.get(j - 1));
-
-			a.set(j, (HolonBody) tmp);
-		}
-		for (int i = 0; i < subCount; i++)
-			pos.add(a.get(i).position);
-		return pos;
-	}
-
-	public void checkCollisions() {
-		insertionSort(bodies);
-
-		for (int i = 0; i < subCount; i++) {
-			// Ball to Ball collision
-			for (int j = i + 1; j < subCount; j++) {
-				if ((bodies.get(i).position.getX() + bodies.get(i).getRadius()) < (bodies.get(j).position.getX()
-						- bodies.get(j).getRadius()))
-					break;
-
-				if ((bodies.get(i).position.getY() + bodies.get(i).getRadius()) < (bodies.get(j).position.getY()
-						- bodies.get(j).getRadius())
-						|| (bodies.get(j).position.getY() + bodies.get(j).getRadius()) < (bodies.get(i).position.getY()
-								- bodies.get(i).getRadius()))
-					continue;
-
-				bodies.get(i).resolveCollision(bodies.get(j));
-
-			}
-		}
-
-	}
-
+	
 	// calc the center of the canvas
 	public void calcCenter() {
 		center = this.getSize();
@@ -485,23 +257,25 @@ public class HolonCanvas extends JPanel implements MouseWheelListener, MouseList
 			float cr = bodies.get(i).getRadius();
 			if (e.getX() - cr <= cx && e.getY() - cr <= cy && e.getX() + cr >= cx && e.getY() + cr >= cy) {
 				controller.addSelectedHolonBody(bodies.get(i).getId());
+				hCController.setBodyToDrag(bodies.get(i).getId());
 				toDrag = bodies.get(i);
 				break;
 			} else {
 				controller.addSelectedHolonBody(-1);
 				toDrag = null;
 			}
+			hCController.setBodyToDrag(-1);
 		}
 	}
 
 	@Override
 	public void mouseReleased(MouseEvent e) {
-		beingDragged = false;
+		hCController.setDrag(false);
 	}
 
 	@Override
 	public void mouseDragged(MouseEvent e) {
-		beingDragged = true;
+		hCController.setDrag(true);
 		if (toDrag != null) {
 			toDrag.position = new Vector2d(e.getX(), e.getY());
 		}
@@ -511,6 +285,5 @@ public class HolonCanvas extends JPanel implements MouseWheelListener, MouseList
 	@Override
 	public void mouseMoved(MouseEvent e) {
 		// TODO Auto-generated method stub
-
 	}
 }