Browse Source

added a holarchy window + virtual neighborhood relation

DESKTOP-L7IQHES\Jonas 2 years ago
parent
commit
7ddd247121

BIN
exampleNetworks/MyExamples/example01.holon


BIN
exampleNetworks/MyExamples/t.holon


+ 43 - 3
src/classes/Holon.java

@@ -4,9 +4,12 @@ import java.util.ArrayList;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.List;
+import java.util.UUID;
 
+import classes.holonControlUnit.HolonControlUnit;
 import ui.controller.Control;
 import ui.model.DecoratedNetwork;
+import ui.model.Model;
 
 public class Holon {
 	public String name = new String();
@@ -16,21 +19,33 @@ public class Holon {
 	//HolonObject is the lowest representation of a holon.
 	private final HolonObject holonObject;
 	public final boolean isPhysical; 
+	public HolonControlUnit holonControlUnit;
+	private String uniqueID;
+	public Model model;
 	
-	public Holon(String name) {
+	public Holon(String name, Model model) {
 		this.name = name;
 		this.holonObject = null;
 		isPhysical = false;
+		this.holonControlUnit = new HolonControlUnit(this);
+		this.uniqueID = UUID.randomUUID().toString();
+		this.model = model;
+//		System.out.println("Created new Holon "+name+"   "+this.uniqueID);
 	}
-	public Holon(HolonObject object) {
+	
+	public Holon(HolonObject object, Model model) {
 		holonObject = object;
 		object.holon = this;
 		name = object.getName();
+		this.holonControlUnit = new HolonControlUnit(this);
 		elements.addAll(object.getElements());
 		for(HolonElement ele : elements) {
 			ele.holon = this;
 		}
 		isPhysical = true;
+		this.uniqueID = UUID.randomUUID().toString();
+		this.model = model;
+//		System.out.println("Created new Holon "+name+"   "+this.uniqueID);
 	}
 	
 	
@@ -47,18 +62,25 @@ public class Holon {
 	}
 	
 	public void addChild(Holon child) {
+		if(!this.model.getHolonsByID().containsKey(child.getUniqueID()))
+			return;
 		child.parent = this;
 		childHolons.add(child);
+		this.holonControlUnit.addSubHolon(child);
+//		System.out.println("Holon "+this.name+" added new child holon "+child.name);
 	}
 	
 	public void addChildHolon(Holon child, int index) {
 		child.parent = this;
 		childHolons.add(index, child);
+		this.holonControlUnit.addSubHolon(child);
+//		System.out.println("Holon "+this.name+" added new child holon "+child.name);
 	}
 	
 	public void removeChildHolon(Holon child) {
 		child.parent = null;
 		childHolons.remove(child);
+		this.holonControlUnit.getHierarchyController().removeSubHolon(child.getUniqueID());
 	}
 	
 	public void removeFromParent() {
@@ -75,6 +97,13 @@ public class Holon {
 	public Holon getParent() {
 		return parent;
 	}
+	
+	public void setParent(Holon parent) {
+//		System.out.println("Holon "+this.name+" replaced parent "+this.parent.name+" with "+parent.name);
+		this.parent = parent;
+		this.holonControlUnit.setSuperHolon(parent);
+	}
+	
 	public HolonObject getHolonObject() {
 		return holonObject;
 	}
@@ -117,7 +146,8 @@ public class Holon {
 	
 	
 	public Holon cloneWithoutParent() {
-		Holon cloned = new Holon(this.name);
+		Holon cloned = new Holon(this.name, this.model);
+		model.getHolonsByID().put(cloned.getUniqueID(), cloned);
 		cloned.childHolons = this.childHolons;
 		cloned.elements = this.elements;
 		return cloned;
@@ -178,6 +208,16 @@ public class Holon {
 		
 	}
 	
+	public void addNewVirtualNeighbor(String virtualNeighbor) {
+		if(!this.equals(virtualNeighbor)) {
+			this.holonControlUnit.addNewVirtualNeighbor(virtualNeighbor);
+		}
+	}
+	
+	public String getUniqueID() {
+		return uniqueID;
+	}
+	
 }
 
 

+ 87 - 0
src/classes/holonControlUnit/CommunicationModule.java

@@ -0,0 +1,87 @@
+package classes.holonControlUnit;
+
+import classes.Holon;
+import classes.holonControlUnit.messages.Message;
+import classes.holonControlUnit.messages.NeighborhoodMsg;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.Set;
+
+import com.google.gson.Gson;
+
+/**
+ * this class is responsable for communication between holons
+ * @author Jonas
+ *
+ */
+public class CommunicationModule {
+	
+	private HolonControlUnit hcu;
+	private Gson gson;
+
+	public enum MessageType {
+		ORDER, NEIGHBORHOOD
+	}
+	
+	public CommunicationModule(HolonControlUnit owner) {
+		this.hcu = owner;
+		this.gson = new Gson();
+	}
+
+	public void sendMsg(String receiver, MessageType type, String body) {
+		//send msg to holon receiver
+		Message msg = new Message(this.hcu.getHolon().getUniqueID(), receiver, type, body);
+//		System.out.println("Holon "+hcu.getHolon().getUniqueID()+" send message: "+msg);
+		//get receiver through his uniqueID
+		Holon h = this.hcu.getHolon().model.getHolonsByID().get(receiver);
+		if(h == null) {
+			System.err.println("Could not find Holon: "+receiver+"\t in holons: "+this.hcu.getHolon().model.getHolonsByID());
+			return;
+		}
+		h.holonControlUnit.getCommunicator().receiveMsg(gson.toJson(msg));
+	}
+	
+	public void receiveMsg(String message) {
+		Message msg = this.gson.fromJson(message, Message.class);
+//		System.out.println("Holon "+hcu.getHolon().getUniqueID()+" received message: "+message);
+		
+		if(!msg.getReceiver().equals(this.hcu.getHolon().getUniqueID()))
+			throw new RuntimeException("Missleaded message:\n"+message);
+		
+		switch (msg.getType()) {
+			case ORDER:
+				break;
+			case NEIGHBORHOOD:
+				receiveNewVNeighbor(msg);
+				break;
+			default:
+				throw new RuntimeException("Unknown message type:\n"+message);
+		}
+	}
+	
+	private void receiveNewVNeighbor(Message msg) {
+		NeighborhoodMsg nMsg = this.gson.fromJson(msg.getBody(), NeighborhoodMsg.class);
+		ArrayList<String> neighbors = nMsg.getNeighbors();
+		switch(nMsg.getType()) {
+			case NEW_VIRTUAL_NEIGHBOR:
+				this.hcu.getHierarchyController().addVirtualNeighbors(neighbors);
+				break;
+			case REMOVE_VIRTUAL_NEIGHBOR:
+				this.hcu.getHierarchyController().removeVirtualNeighbors(neighbors);
+				break;
+			case NEW_PHYSICAL_NEIGHBOR:
+				break;
+			case REMOVE_PHYSICAL_NEIGHBOR:
+				break;
+			default:
+				throw new RuntimeException("Unknown neighborhood type:\n"+msg);
+		}
+//		System.out.println("Holon "+hcu.getHolon().name+" received new v neighbor "+v.getNewVirtualNeighbor());
+	}
+	
+	public Gson getGson() {
+		return this.gson;
+	}
+	
+}

+ 5 - 0
src/classes/holonControlUnit/FlexibilityManager.java

@@ -0,0 +1,5 @@
+package classes.holonControlUnit;
+
+public class FlexibilityManager {
+
+}

+ 5 - 0
src/classes/holonControlUnit/ForecastComputationUnit.java

@@ -0,0 +1,5 @@
+package classes.holonControlUnit;
+
+public class ForecastComputationUnit {
+
+}

+ 102 - 0
src/classes/holonControlUnit/HierarchyControlUnit.java

@@ -0,0 +1,102 @@
+package classes.holonControlUnit;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.Set;
+
+import classes.Holon;
+import classes.holonControlUnit.messages.NeighborhoodMsg;
+
+public class HierarchyControlUnit {
+
+	private HolonControlUnit hcu;
+	private ArrayList<String> subHolons;
+	private ArrayList<String> physicalNeighbors;
+	private ArrayList<String> virtualNeighbors;
+	
+	public HierarchyControlUnit(HolonControlUnit hcu) {
+		this.hcu = hcu;
+		this.subHolons = new ArrayList();
+		this.physicalNeighbors = new ArrayList();
+		
+		this.virtualNeighbors = new ArrayList();
+//		if(h.getParent() != null)
+//			this.virtualNeighbors.addAll(h.getParent().childHolons);
+//		System.out.println("created hcu for holon "+h.name);
+//		System.out.println("\tsuperholon"+(h.getParent() != null ? h.getParent().name : ""));
+//		System.out.println("\tsubholons"+h.childHolons.toString());
+//		System.out.println("\tvirtual neighbors"+this.virtualNeighbors.toString());
+//		System.out.println("\tphysical neighbors"+this.physicalNeighbors.toString());
+	}
+	
+	public ArrayList<String> getPhysicalNeighbors() {
+		return physicalNeighbors;
+	}
+
+	public void setPhysicalNeighbors(ArrayList<String> physicalNeighbors) {
+		this.physicalNeighbors = physicalNeighbors;
+	}
+	
+	public void addPhysicalNeighbor(String physicalNeighbor) {
+		this.physicalNeighbors.add(physicalNeighbor);
+	}
+
+	public ArrayList<String> getVirtualNeighbors() {
+		return virtualNeighbors;
+	}
+
+	public void setVirtualNeighbors(ArrayList<String> virtualNeighbors) {
+		this.virtualNeighbors = virtualNeighbors;
+	}
+	
+	public void addSubHolon(String subHolon) {
+//		System.out.println("Holon "+this.hcu.getHolon().getUniqueID()+" adds sub-holon "+subHolon);
+		//propagate new virtual neighbor for all subholons
+		ArrayList<String> list = new ArrayList();
+		list.add(subHolon);
+		String body = this.hcu.getCommunicator().getGson().toJson(new NeighborhoodMsg(NeighborhoodMsg.Type.NEW_VIRTUAL_NEIGHBOR, list));
+//		System.out.println("list: "+list.toString()+" body "+body);
+		for(String sub : this.subHolons) {
+			this.hcu.getCommunicator().sendMsg(sub, CommunicationModule.MessageType.NEIGHBORHOOD, body);
+		}
+		if(this.subHolons.size() > 0) {
+			body = this.hcu.getCommunicator().getGson().toJson(new NeighborhoodMsg(NeighborhoodMsg.Type.NEW_VIRTUAL_NEIGHBOR, this.subHolons));
+			this.hcu.getCommunicator().sendMsg(subHolon, CommunicationModule.MessageType.NEIGHBORHOOD, body);
+		}
+		
+		this.subHolons.add(subHolon);
+	}
+	
+	public void removeSubHolon(String subHolon) {
+		if(!this.subHolons.remove(subHolon))
+			System.err.println("Could not remove sub holon "+subHolon);
+		ArrayList<String> list = new ArrayList();
+		list.add(subHolon);
+		String body = this.hcu.getCommunicator().getGson().toJson(new NeighborhoodMsg(NeighborhoodMsg.Type.REMOVE_VIRTUAL_NEIGHBOR, list));
+		for(String sub : this.subHolons) {
+			this.hcu.getCommunicator().sendMsg(sub, CommunicationModule.MessageType.NEIGHBORHOOD, body);
+		}
+	}
+	
+	public ArrayList<String> getSubHolons() {
+		return this.subHolons;
+	}
+	
+	public void addVirtualNeighbor(String virtualNeighbor) {
+		this.virtualNeighbors.add(virtualNeighbor);
+//		System.out.println("Holon "+this.hcu.getHolon().getUniqueID()+" add virtual neighbor"+virtualNeighbor);
+	}
+	
+	public void addVirtualNeighbors(ArrayList<String> virtualNeighbor) {
+		this.virtualNeighbors.addAll(virtualNeighbor);
+//		System.out.println("Holon "+this.hcu.getHolon().getUniqueID()+" add virtual neighbor"+virtualNeighbor);
+	}
+	
+	public void removeVirtualNeighbor(String virtualNeighbor) {
+		this.virtualNeighbors.remove(virtualNeighbor);
+	}
+
+	public void removeVirtualNeighbors(ArrayList<String> virtualNeighbor) {
+		this.virtualNeighbors.removeAll(virtualNeighbor);
+	}
+}

+ 89 - 0
src/classes/holonControlUnit/HolonControlUnit.java

@@ -0,0 +1,89 @@
+package classes.holonControlUnit;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.Set;
+
+import classes.Holon;
+import classes.holonControlUnit.messages.Message;
+import classes.holonControlUnit.messages.NeighborhoodMsg;
+
+public class HolonControlUnit {
+	
+	private Holon holon, superHolon;
+	private FlexibilityManager flexMan;
+	private ForecastComputationUnit forecaster;
+	private HierarchyControlUnit hierarchyController;
+	private OptimizationManager optimizer;
+	private StateEstimator stateEstimator;
+	private TargetStateAssembler stateAssembler;
+	private CommunicationModule communicator;
+	
+	public HolonControlUnit(Holon h) {
+		this.holon = h;
+		this.hierarchyController = new HierarchyControlUnit(this);
+		this.flexMan = new FlexibilityManager();
+		this.forecaster = new ForecastComputationUnit();
+		this.optimizer = new OptimizationManager();
+		this.stateEstimator = new StateEstimator();
+		this.stateAssembler = new TargetStateAssembler();
+		this.communicator = new CommunicationModule(this);
+	}
+
+	public Holon getSuperHolon() {
+		return superHolon;
+	}
+
+	public void setSuperHolon(Holon superHolon) {
+		this.superHolon = superHolon;
+	}
+
+	public ArrayList<Holon> getSubHolon() {
+		return this.holon.childHolons;
+	}
+	
+	public void addSubHolon(Holon subHolon) {
+		this.hierarchyController.addSubHolon(subHolon.getUniqueID());
+	}
+	
+	public void addNewVirtualNeighbor(String virtualNeighbor) {
+		this.hierarchyController.addVirtualNeighbor(virtualNeighbor);
+	}
+	
+	public void addNewVirtualNeighbors(ArrayList<String> virtualNeighbor) {
+		this.hierarchyController.addVirtualNeighbors(virtualNeighbor);
+	}
+
+	public Holon getHolon() {
+		return holon;
+	}
+
+	public FlexibilityManager getFlexMan() {
+		return flexMan;
+	}
+
+	public ForecastComputationUnit getForecaster() {
+		return forecaster;
+	}
+
+	public HierarchyControlUnit getHierarchyController() {
+		return hierarchyController;
+	}
+
+	public OptimizationManager getOptimizer() {
+		return optimizer;
+	}
+
+	public StateEstimator getStateEstimator() {
+		return stateEstimator;
+	}
+
+	public TargetStateAssembler getStateAssembler() {
+		return stateAssembler;
+	}
+
+	public CommunicationModule getCommunicator() {
+		return communicator;
+	}
+
+}

+ 5 - 0
src/classes/holonControlUnit/OptimizationManager.java

@@ -0,0 +1,5 @@
+package classes.holonControlUnit;
+
+public class OptimizationManager {
+
+}

+ 5 - 0
src/classes/holonControlUnit/StateEstimator.java

@@ -0,0 +1,5 @@
+package classes.holonControlUnit;
+
+public class StateEstimator {
+
+}

+ 5 - 0
src/classes/holonControlUnit/TargetStateAssembler.java

@@ -0,0 +1,5 @@
+package classes.holonControlUnit;
+
+public class TargetStateAssembler {
+
+}

+ 42 - 0
src/classes/holonControlUnit/messages/Message.java

@@ -0,0 +1,42 @@
+package classes.holonControlUnit.messages;
+
+import classes.Holon;
+import classes.holonControlUnit.CommunicationModule.MessageType;
+
+public class Message {
+
+	private String sender;
+	private String receiver;
+	private MessageType type;
+	private String body;
+	
+	public Message(String sender, String receiver, MessageType type, String body) {
+		super();
+		this.sender = sender;
+		this.receiver = receiver;
+		this.type = type;
+		this.body = body;
+	}
+
+	@Override
+	public String toString() {
+		return "Message [sender=" + sender + ", receiver=" + receiver + ", type=" + type + ", body=" + body + "]";
+	}
+
+	public String getSender() {
+		return sender;
+	}
+
+	public String getReceiver() {
+		return receiver;
+	}
+
+	public MessageType getType() {
+		return type;
+	}
+
+	public String getBody() {
+		return body;
+	}
+	
+}

+ 32 - 0
src/classes/holonControlUnit/messages/NeighborhoodMsg.java

@@ -0,0 +1,32 @@
+package classes.holonControlUnit.messages;
+
+import java.util.ArrayList;
+
+import classes.Holon;
+
+public class NeighborhoodMsg {
+
+	public enum Type { NEW_VIRTUAL_NEIGHBOR, REMOVE_VIRTUAL_NEIGHBOR, NEW_PHYSICAL_NEIGHBOR, REMOVE_PHYSICAL_NEIGHBOR }
+	private Type type;
+	private ArrayList<String> neighbors;
+
+	public NeighborhoodMsg(Type type, ArrayList<String> newVirtualNeighbor) {
+		super();
+		this.type = type;
+		this.neighbors = newVirtualNeighbor;
+	}
+
+	@Override
+	public String toString() {
+		return "NeighborhoodMsg [type=" + type + ", newVirtualNeighbor=" + neighbors + "]";
+	}
+
+	public ArrayList<String> getNeighbors() {
+		return neighbors;
+	}
+
+	public Type getType() {
+		return type;
+	}
+	
+}

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

@@ -50,7 +50,8 @@ public class CanvasController {
 		model.getCvsObjIdx().put(object.getId(), model.getObjectsOnCanvas().size());
 		model.getObjectsOnCanvas().add(object);
 		if(object instanceof HolonObject) {
-			Holon holon = new Holon((HolonObject)object);
+			Holon holon = new Holon((HolonObject)object, model);
+//			model.getHolonsByID().put(holon.getUniqueID(), holon);
 			model.getStateHolon().addChild(holon);
 		}
 		
@@ -145,6 +146,7 @@ public class CanvasController {
 		model.getObjectsOnCanvas().remove(obj);
 		if(obj instanceof HolonObject) {
 			HolonObject holonObject  = (HolonObject) obj;
+			model.getHolonsByID().remove(holonObject.holon.getUniqueID(), holonObject.holon);
 			removeHolon(holonObject.holon);
 			holonObject.holon = null;
 		}

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

@@ -53,8 +53,6 @@ public class Control {
     private int rand;
     
     
-    
-    
     public Event OnSelectionUpdate = new Event();
 
     

+ 4 - 2
src/ui/controller/LoadController.java

@@ -203,16 +203,18 @@ public class LoadController {
     
 	private void deserializeHolon(Holon parent, JsonObject holonJson,
 			HashMap<Integer, AbstractCanvasObject> objDispatch) {
+		System.out.println("deserialize holon from parent"+parent.name);
 		int objId = holonJson.get("HolonObjectID").getAsInt();
 		String name = holonJson.get("Name").getAsString();
 		Holon created;
 		if(objId != -1) {
 			HolonObject holonObject = (HolonObject) objDispatch.get(objId);
-			created = new Holon(holonObject);
+			created = new Holon(holonObject, model);
 			created.name = name;
 		}else {
-			created = new Holon(name);
+			created = new Holon(name, model);
 		}
+		model.getHolonsByID().put(created.getUniqueID(), created);
 		JsonArray array = holonJson.get("ChildHolons").getAsJsonArray();
 		for(JsonElement ele : array) {
 			deserializeHolon(created, ele.getAsJsonObject() , objDispatch);

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

@@ -5,6 +5,7 @@ import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.LinkedList;
 import java.util.List;
+import java.util.Map;
 import java.util.stream.Collectors;
 
 import javax.swing.JTable;
@@ -128,7 +129,9 @@ public class Model {
     private PropertyTable tableModelHolonElementSingle;
     private DefaulTable tableModelProperties;
     private HashMap<Integer, GroupNode> hashcodeMap = new HashMap<>();
-    private Holon stateHolon = new Holon("All Holons");
+    private Holon stateHolon = new Holon("All Holons", this);
+    
+    private Map<String, Holon> holonsByID = new HashMap();
 
     private Gson gson;
 
@@ -152,6 +155,7 @@ public class Model {
         getPropertyTable().setColumnIdentifiers(colNames);
         setTableHolonElement(new JTable());
         initGson();
+		this.holonsByID.put(stateHolon.getUniqueID(), stateHolon);
     }
 
     /**
@@ -874,4 +878,9 @@ public class Model {
 			else if(aCps instanceof HolonSwitch)switchsOnCanvas.add((HolonSwitch) aCps);
 		}
 	}
+
+	public Map<String, Holon> getHolonsByID() {
+		return holonsByID;
+	}
+	
 }

+ 1 - 1
src/ui/view/FlexWindow.java

@@ -61,7 +61,7 @@ import ui.controller.FlexManager;
 import ui.controller.FlexManager.FlexState;
 import ui.controller.FlexManager.FlexWrapper;
 import ui.model.Model;
-import utility.ImageImport;
+import util.ImageImport;
 
 
 public class FlexWindow extends JFrame {

+ 8 - 1
src/ui/view/GUI.java

@@ -92,8 +92,8 @@ import ui.model.DecoratedState;
 import ui.model.Model;
 import ui.model.Model.FairnessModel;
 import ui.view.CreateNewDialog.Option;
+import ui.view.holarchy.HolarchyWindow;
 import ui.view.outliner.Outliner;
-import utility.ImageImport;
 import util.Event;
 import util.ImageImport;
 
@@ -2169,6 +2169,13 @@ public class GUI{
 		});
 		openFlexMenuItem.setAccelerator(KeyStroke.getKeyStroke('L', Toolkit.getDefaultToolkit ().getMenuShortcutKeyMask()));
 		menuWindow.add(openFlexMenuItem);
+		//Holarchy View
+		JMenuItem holarchyMenuItem = new JMenuItem("Open Holarchy Panel", new ImageIcon(ImageImport.loadImage("/Button_Images/holon_logic.png").getScaledInstance(20, 20, java.awt.Image.SCALE_SMOOTH)));
+		holarchyMenuItem.addActionListener(actionEvent -> {
+			new HolarchyWindow(holegJFrame, controller);
+		});
+		holarchyMenuItem.setAccelerator(KeyStroke.getKeyStroke('H', Toolkit.getDefaultToolkit ().getMenuShortcutKeyMask()));
+		menuWindow.add(holarchyMenuItem);
 	}
 
 

+ 370 - 0
src/ui/view/holarchy/HolarchyPanel.java

@@ -0,0 +1,370 @@
+package ui.view.holarchy;
+
+import java.awt.Color;
+import java.awt.Graphics;
+import java.awt.Graphics2D;
+import java.awt.event.MouseEvent;
+import java.awt.event.MouseListener;
+import java.awt.geom.Ellipse2D;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.JSeparator;
+import javax.swing.JSlider;
+import javax.swing.SwingConstants;
+import javax.swing.event.ChangeEvent;
+import javax.swing.event.ChangeListener;
+
+import classes.Holon;
+import ui.controller.Control;
+import util.Random;
+
+public class HolarchyPanel extends JPanel {
+	
+	Control control;
+	HolarchyWindow parentFrame;
+	JLabel layerLabelTitle;
+	JSlider slider;
+	JSeparator sep, sep2;
+	int displayedLayer;
+	int minRadius = 24;
+	Holon root;
+	ArrayList<Map<Ellipse2D, Map<Ellipse2D, Holon>>> ellipsesChild;
+	ArrayList<Map<Ellipse2D, Holon>> ellipses;
+	ArrayList<ArrayList<Holon>> layeredHolons;
+	ArrayList<Ellipse2D> surroundings;
+	Map<Holon, Color> coloredHolons;
+	
+	public HolarchyPanel(HolarchyWindow parentFrame, Control control) {
+		this.control = control;
+		this.parentFrame = parentFrame;
+		this.root = control.getModel().getStateHolon();
+		
+		this.setBounds(0, 0, parentFrame.getWidth()*4/5, parentFrame.getHeight());
+		this.setLayout(null);
+		this.setBackground(Color.white);
+		this.addMouseListener(mouseListener);
+		
+		this.layerLabelTitle = new JLabel("Layer");
+		this.layerLabelTitle.setBounds(5, 5, 50, 20);
+		this.layerLabelTitle.setHorizontalAlignment(SwingConstants.CENTER);
+		this.add(this.layerLabelTitle);
+
+		this.slider = new JSlider();
+		this.slider.setOrientation(SwingConstants.VERTICAL);
+		this.slider.setBounds(5, 30, 50, 200);
+		this.slider.setPaintLabels(true);
+		this.slider.setPaintTicks(true);
+		this.slider.setSnapToTicks(true);
+		this.slider.addChangeListener(this.sliderChangeListener);
+		this.slider.setValue(0);
+		this.slider.setInverted(true);
+		this.slider.setFocusable(false);
+		this.slider.setBackground(Color.white);
+		this.add(slider);
+		
+		this.sep = new JSeparator(SwingConstants.VERTICAL);
+		this.sep.setBounds(60, 0, 1, 235);
+		this.add(this.sep);
+		this.sep2 = new JSeparator(SwingConstants.HORIZONTAL);
+		this.sep2.setBounds(0, 235, 60, 1);
+		this.add(this.sep2);
+		
+		this.ellipses = new ArrayList();
+		this.ellipsesChild = new ArrayList();
+		this.displayedLayer = 0;
+		this.layeredHolons = new ArrayList();
+		this.surroundings = new ArrayList();
+		this.coloredHolons = new HashMap();
+		getAllHolons();
+		setSliderMax(this.layeredHolons.size());
+		createAllLayers();
+		generateColorSet();
+	}
+		
+	public void paintComponent(Graphics g) {
+		super.paintComponent(g);
+		paintLayer(g, this.displayedLayer);
+	}
+	
+	public void displayLayer(int layer) {
+		this.displayedLayer = layer;
+		this.repaint();
+	}
+	
+	public void paintLayer(Graphics g, int layer) {
+		this.displayedLayer = layer;
+		Graphics2D g2 = (Graphics2D) g;
+		
+		//resize panel
+		Ellipse2D surrounding = this.surroundings.get(this.displayedLayer);
+		if(surrounding.getWidth() > this.getWidth()) {
+			this.setSize((int) surrounding.getWidth(), this.getHeight());
+//			this.parentFrame.resizeScrollPane((int) surrounding.getWidth(), this.getHeight());
+		}
+		if(surrounding.getHeight() > this.getHeight()) {
+			this.setSize(this.getWidth(), (int) surrounding.getHeight());
+//			this.parentFrame.resizeScrollPane(this.getWidth(), (int) surrounding.getHeight());
+		}
+		
+//		System.out.println("painting layer "+layer+"#elements="+this.ellipses.get(layer).size());
+		for(Ellipse2D e : this.ellipses.get(this.displayedLayer).keySet()) {
+//			System.out.println("paint ellipse");
+			//draw ellipse
+			g2.setColor( this.coloredHolons.get(this.ellipses.get(this.displayedLayer).get(e)) );
+			g2.draw(e);
+			//draw child ellipses and add them to global list
+			for(Ellipse2D e2 : this.ellipsesChild.get(layer).get(e).keySet()) {
+				g2.setColor( this.coloredHolons.get(this.ellipsesChild.get(layer).get(e).get(e2)) );
+				g2.draw(e2);
+			}
+		}
+	}
+	
+	public void createAllLayers() {
+		for(int layer=0; layer<this.layeredHolons.size(); layer++) {
+//			System.out.println("creating layer "+layer+" #elements="+this.layeredHolons.get(layer).size());
+			this.ellipsesChild.add(layer, new HashMap());
+//			System.out.println("creating ellipse");
+			//estimate the required area, center if it is smaller than the panels size
+			Ellipse2D surrounding = estimateSurrounding(60, 0, layer);
+			double newX = surrounding.getX(), newY = surrounding.getY();
+			if(surrounding.getWidth() <= this.getWidth()) {
+				double diff = this.getWidth() - surrounding.getWidth();
+				newX = diff/2;
+			}
+			if(surrounding.getHeight() <= this.getHeight()) {
+				double diff = this.getHeight() - surrounding.getHeight();
+				newY = diff/2;
+			}
+			surrounding = new Ellipse2D.Double(newX, newY, surrounding.getWidth(), surrounding.getHeight());
+			this.surroundings.add(layer, surrounding);
+			
+			//create ellipse for each holon
+			this.ellipses.add(layer, placeHolons(this.layeredHolons.get(layer), surrounding, true));
+//			System.out.println("paint surrounding width="+surrounding.getWidth()+" height="+surrounding.getHeight());
+//			System.out.println("pending holons "+this.ellipses.get(layer).size());
+			for(Ellipse2D e : this.ellipses.get(layer).keySet()) {
+				//draw child ellipses and add them to global list
+				Map<Ellipse2D, Holon> ellipses2 = placeHolons(ellipses.get(layer).get(e).childHolons, e, false);
+				this.ellipsesChild.get(layer).put(e, ellipses2);
+			}
+		}
+	}
+	
+	/**
+	 * randomly place an ellipse for each holon in holons inside the given ellipse without overlapping
+	 * @param holons
+	 * @param surrounding
+	 * @param drawChildren
+	 * @return
+	 */
+	public Map<Ellipse2D, Holon> placeHolons(List<Holon> holons, Ellipse2D surrounding, boolean drawChildren) {
+		double startX = surrounding.getX();
+		double startY = surrounding.getY();
+		double width = surrounding.getWidth();
+		double height = surrounding.getHeight();
+		
+		Map<Ellipse2D, Holon> shapes = new HashMap();
+		int abord = 0;
+		int i = 0;
+		
+		while(shapes.size() < holons.size() && abord < 1000) {
+			Holon h = holons.get(i);
+			int radius = this.minRadius;
+			if(drawChildren)
+				radius = this.minRadius * (h.getChildCount()+1) + 10;
+			
+			//randomly place an ellipse for the holon
+			double x = startX + (width * Math.random());
+			double y = startY + (height * Math.random());
+			//check if ellipse is inside the surrounding
+			boolean overlap = !surrounding.contains(x, y, radius*2, radius*2);
+			if(overlap) {
+				continue;
+			}
+			Ellipse2D e = new Ellipse2D.Double(x-5, y-5, radius*2+10, radius*2+10);
+			
+			//check whether or not the random ellipse overlaps with an existing one
+			for(Ellipse2D e2 : shapes.keySet()) {
+				if(e.intersects(e2.getX()-5, e2.getY()-5, e2.getWidth()+10, e2.getHeight()+10)) {
+					overlap = true;
+					break;
+				}
+			}
+//			System.out.println("try to add ellipse "+i+" x="+e.getX()+" y="+e.getY());
+
+			abord++;
+			//if not add the ellipse to the already existing ones
+			if(!overlap) {
+				shapes.put(e, h);
+//				System.out.println("added ellipse "+i+" at ("+e.getX()+", "+e.getY()+")");
+				i++;
+				abord = 0;
+			}
+		}
+		
+		return shapes;
+	}
+	
+	public Ellipse2D estimateSurrounding(int x, int y, int layer) {
+		if(this.layeredHolons == null || this.layeredHolons.size() < layer+1)
+			return new Ellipse2D.Double(x, y, Integer.MAX_VALUE, Integer.MAX_VALUE);
+
+		int w = 0;
+		for(Holon h : this.layeredHolons.get(layer)) {
+			w += this.minRadius * (h.getChildCount()+1);
+		}
+		w = w * 4 + 10;
+		
+		return new Ellipse2D.Double(x, y, w, w);
+	}
+	
+	/**
+	 * @deprecated
+	 * calculate distance between the two specified ellipses and check if they overlap
+	 * @param e1
+	 * @param e2
+	 * @return
+	 */
+	public boolean overlap(Ellipse2D e1, Ellipse2D e2) {
+		int dist = (int) Math.sqrt( Math.pow((e1.getCenterX()+e2.getCenterX()), 2) + Math.pow((e1.getCenterY()+e2.getCenterY()), 2) );
+		
+		if(dist < e1.getWidth()/2 + e2.getWidth()/2 + 10)
+			return true;
+		return false;
+	}
+	
+	public void getAllHolons() {
+		this.layeredHolons.add(this.root.childHolons);
+		
+		//TODO: potential infinit loop
+		while(true) {
+			//new layer
+			ArrayList<Holon> children = new ArrayList();
+			for(Holon h : this.layeredHolons.get(this.layeredHolons.size()-1)) {
+				children.addAll(h.childHolons);
+			}
+			if(children.size() > 0) {
+				this.layeredHolons.add(children);
+			} else {
+				break;
+			}
+		}
+	}
+	
+	public void setSliderMax(int n) {
+		if(this.slider == null || n < 0)
+			return;
+		this.slider.setMaximum(n-1);
+		if(n < 11) {
+			this.slider.setMajorTickSpacing(1);
+		} else if (n < 101) {
+			this.slider.setMajorTickSpacing(10);
+			this.slider.setMinorTickSpacing(1);
+		} else {
+			this.slider.setMajorTickSpacing(100);
+			this.slider.setMinorTickSpacing(10);
+		}
+	}
+	
+	/**
+	 * generate a distinct color for each Holon in each layer
+	 */
+	public void generateColorSet() {
+		for(int layer=0; layer<this.layeredHolons.size(); layer++) {
+			int numColors = 0;
+			numColors = this.layeredHolons.get(layer).size();
+			if(numColors <= 0)
+				continue;
+//			System.out.println("generating colors for "+numColors+" holons");
+			ArrayList<Color> colors = new ArrayList();
+			float hue = Random.nextFloatInRange(0, 1);
+			for(float i = 0; i < 360; i += 360 / numColors) {
+			    hue += 0.618033988749895f; 
+			    float saturation = 0.5f; //90 + Random.nextFloatInRange(0, 10);
+			    float lightness = 0.95f; //50 + Random.nextFloatInRange(0, 10);
+			    Color c = Color.getHSBColor(hue%1, saturation, lightness);
+	
+			    colors.add(c);
+//				System.out.println("generated color "+c.toString()+" by h "+hue+" sat "+saturation+" light "+lightness);
+			}
+			
+			for(int j=0;j<this.layeredHolons.get(layer).size(); j++) {
+				this.coloredHolons.put(this.layeredHolons.get(layer).get(j), colors.get(j));
+//				System.out.println("generated color "+colors.get(j).toString()+" for holon "+this.layeredHolons.get(layer).get(j));
+			}
+		}
+	}
+	
+	MouseListener mouseListener = new MouseListener() {
+
+		@Override
+		public void mouseClicked(MouseEvent arg0) {
+//			System.out.println("mouse click at ("+arg0.getX()+","+arg0.getY()+")");
+			//Get clicked Holon
+			for(Ellipse2D e : ellipses.get(displayedLayer).keySet()) {
+				if(e.contains(arg0.getX(), arg0.getY())) {
+					//found ellipse
+					boolean child = false;
+					//check if one its children was clicked
+					for(Ellipse2D e2 : ellipsesChild.get(displayedLayer).get(e).keySet()) {
+						if(e2.contains(arg0.getX(), arg0.getY())) {
+							//child was clicked
+							child = true;
+							parentFrame.displayHolonInfos(ellipsesChild.get(displayedLayer).get(e).get(e2));
+//							System.out.println("child holon "+ellipsesChild.get(e).get(e2).name+" was clicked");
+							break;
+						}
+					}
+					if(!child) {
+						//no child was clicked
+						parentFrame.displayHolonInfos(ellipses.get(displayedLayer).get(e));
+//						System.out.println("holon "+ellipses.get(e).name+" was clicked");
+					}
+					break;
+				}
+			}
+			
+		}
+
+		@Override
+		public void mouseEntered(MouseEvent arg0) {
+			//not important
+		}
+
+		@Override
+		public void mouseExited(MouseEvent arg0) {
+			//not important
+		}
+
+		@Override
+		public void mousePressed(MouseEvent arg0) {
+			//not important
+		}
+
+		@Override
+		public void mouseReleased(MouseEvent arg0) {
+			//not important
+		}
+		
+	};
+	
+	ChangeListener sliderChangeListener = new ChangeListener() {
+
+		@Override
+		public void stateChanged(ChangeEvent arg0) {
+			JSlider source = (JSlider) arg0.getSource();
+			if(!source.getValueIsAdjusting()) {
+				displayLayer(source.getValue());
+				parentFrame.clearInfos();
+			}
+		}
+		
+	};
+
+}

+ 156 - 0
src/ui/view/holarchy/HolarchyTreePanel.java

@@ -0,0 +1,156 @@
+package ui.view.holarchy;
+
+import java.awt.BorderLayout;
+import java.awt.Component;
+import java.awt.Image;
+import java.awt.event.MouseAdapter;
+import java.awt.event.MouseEvent;
+import java.awt.image.BufferedImage;
+
+import javax.swing.Icon;
+import javax.swing.ImageIcon;
+import javax.swing.JCheckBoxMenuItem;
+import javax.swing.JMenuItem;
+import javax.swing.JPanel;
+import javax.swing.JPopupMenu;
+import javax.swing.JTree;
+import javax.swing.SwingUtilities;
+import javax.swing.ToolTipManager;
+import javax.swing.tree.DefaultMutableTreeNode;
+import javax.swing.tree.DefaultTreeCellRenderer;
+import javax.swing.tree.TreePath;
+import javax.swing.tree.TreeSelectionModel;
+
+import classes.Holon;
+import classes.HolonElement;
+import classes.HolonObject;
+import ui.controller.Control;
+import ui.view.outliner.TreeUtils;
+import util.ImageImport;
+
+public class HolarchyTreePanel extends JPanel {
+	private Control control; 
+	private JTree holonTree;
+	private DefaultMutableTreeNode root;
+	private HolarchyWindow parentFrame;
+	
+	public HolarchyTreePanel(HolarchyWindow parentFrame, Control control) {
+		this.control = control;
+		this.setLayout(new BorderLayout());
+		this.parentFrame = parentFrame;
+		initilizePanel();
+	}
+
+	private void initilizePanel() {
+		holonTree = generateTree();
+		holonTree.setCellRenderer(new HolonJtreeRenderer());
+        holonTree.getSelectionModel().setSelectionMode(
+                TreeSelectionModel.SINGLE_TREE_SELECTION);
+        ToolTipManager.sharedInstance().registerComponent(holonTree);
+        TreeUtils.expand(holonTree);
+        holonTree.setRootVisible(true);
+        holonTree.setEditable(true);
+		this.add(TreeUtils.makePanelFromTree(holonTree));
+	}
+
+	private JTree generateTree() {
+		root = generateFromHolon(control.getModel().getStateHolon());
+		return new JTree(root);
+	}
+	
+	private DefaultMutableTreeNode generateFromHolon(Holon holon) {
+		DefaultMutableTreeNode node = new DefaultMutableTreeNode(new HolonInfo(holon));
+		for(Holon child : holon.getChildView()) {
+			node.add(generateFromHolon(child));
+		}
+		return node;
+	}
+	
+	private void updateTreeStructure() {
+		holonTree.clearSelection();
+		root.removeAllChildren();
+		Holon holon = control.getModel().getStateHolon();
+		for(Holon child : holon.getChildView()) {
+			root.add(generateFromHolon(child));
+		}
+		holonTree.updateUI();
+		TreeUtils.expand(holonTree);
+	}
+	
+	interface HolonNode{
+		public Icon getIcon(); 
+		public String getToolTip();
+		public void SetName(String name);
+	}
+	static final Icon holonIcon = new ImageIcon(ImageImport.loadImage("/Button_Images/holon_logic.png",16,16));
+	static final Icon holonPhysicalIcon = new ImageIcon(ImageImport.loadImage("/Button_Images/holon_physical.png",16,16));
+	static final String holonToolTip = "Holon";
+	class HolonInfo implements HolonNode{
+		private Holon holon;
+		HolonInfo(Holon holon){
+			this.holon = holon;
+		}
+		@Override
+		public String toString(){
+			return holon.name+"   "+holon.getUniqueID();
+		}
+		
+		public Holon getElement()
+		{
+			return holon;
+		}
+		
+		public void AddElement(HolonElement element) {
+			if(element.holon != null) {
+				element.holon.removeElement(element);
+			}
+			holon.addElement(element);
+		}
+		public void AddHolon(Holon holon) {
+			holon.removeFromParent();
+			this.holon.addChild(holon);
+		}
+		@Override
+		public Icon getIcon() {
+			BufferedImage image = new BufferedImage(16, 16, BufferedImage.TYPE_INT_BGR);
+			for(int i=0; i<16; i++) {
+				for(int j=0; j<16; j++) {
+					image.setRGB(i, j, parentFrame.holarchyPanel.coloredHolons.get(this.holon).getRGB());
+				}
+			}
+			return new ImageIcon(image);
+//			return holon.isPhysical? holonPhysicalIcon : holonIcon;
+		}
+		@Override
+		public String getToolTip() {
+			return holonToolTip;
+		}
+		@Override
+		public void SetName(String name) {
+			holon.name = name;
+		}
+		
+	}
+	
+	//Cell Display
+	class HolonJtreeRenderer extends DefaultTreeCellRenderer {
+		
+	    public Component getTreeCellRendererComponent(
+	                        JTree tree,
+	                        Object value,
+	                        boolean isSelected,
+	                        boolean expanded,
+	                        boolean leaf,
+	                        int row,
+	                        boolean hasFocus) {
+	    	 super.getTreeCellRendererComponent(tree, value, isSelected, expanded, leaf, row, hasFocus);
+	         DefaultMutableTreeNode node = (DefaultMutableTreeNode) value;
+	         HolonNode Node = (HolonNode) node.getUserObject();
+	         if(row != 0) {
+	        	 this.setIcon(Node.getIcon());
+	        	 this.setToolTipText(Node.getToolTip());	        	 
+	         }
+	         return this;
+	    }
+	}
+}

+ 75 - 0
src/ui/view/holarchy/HolarchyWindow.java

@@ -0,0 +1,75 @@
+package ui.view.holarchy;
+
+import javax.swing.JFrame;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.JScrollPane;
+import javax.swing.JSeparator;
+import javax.swing.JSlider;
+import javax.swing.JSplitPane;
+import javax.swing.SwingConstants;
+import javax.swing.event.ChangeEvent;
+import javax.swing.event.ChangeListener;
+
+import classes.Holon;
+import util.ImageImport;
+
+public class HolarchyWindow extends JFrame {
+
+	JFrame parentFrame;
+	JSeparator sep;
+	HolarchyPanel holarchyPanel;
+	HolonInfoPanel infoPanel;
+	HolarchyTreePanel treePanel;
+	ui.controller.Control  controller;
+	public boolean isClosed = false;
+	
+	public HolarchyWindow(JFrame parentFrame, ui.controller.Control  controller){
+		this.controller = controller;
+		
+		setBounds(0, 0, parentFrame.getWidth()-200, parentFrame.getHeight()-100);
+		this.setIconImage(ImageImport.loadImage("/Images/Holeg.png", 30, 30));
+		this.setTitle("Holarchy");
+		setLocationRelativeTo(parentFrame);
+		this.setVisible(true);
+		this.addWindowListener(new java.awt.event.WindowAdapter() {
+		    @Override
+		    public void windowClosing(java.awt.event.WindowEvent windowEvent) {
+		    	isClosed = true;
+		    }
+		});
+		
+		this.sep = new JSeparator(SwingConstants.HORIZONTAL);
+		this.sep.setBounds(0, 0, this.getWidth(), 1);
+		this.add(this.sep);
+		
+		this.holarchyPanel = new HolarchyPanel(this, controller);
+		this.holarchyPanel.setBounds(66, 0, this.getWidth()*4/5-66, this.getHeight());
+		
+		this.infoPanel = new HolonInfoPanel(this, controller);
+//		this.infoPanel.setBounds(this.getWidth()*4/5+1, 0, this.getWidth()*1/5-1, this.getHeight());
+		
+		this.treePanel = new HolarchyTreePanel(this, controller);
+		
+		JSplitPane infoSplit = new JSplitPane(JSplitPane.VERTICAL_SPLIT, this.infoPanel, new JScrollPane(this.treePanel));
+		infoSplit.setDividerLocation(this.getHeight()/2);
+		
+		JSplitPane splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, this.holarchyPanel, infoSplit);
+		splitPane.setDividerLocation(this.getWidth()*4/5);
+		splitPane.setEnabled(false);
+		this.add(splitPane);
+	}
+	
+	public void displayHolonInfos(Holon h) {
+		if(this.infoPanel == null)
+			return;
+		this.infoPanel.displayInfos(h);
+	}
+	
+	public void clearInfos() {
+		if(this.infoPanel == null)
+			return;
+		this.infoPanel.clearInfos();
+	}
+	
+}

+ 112 - 0
src/ui/view/holarchy/HolonInfoPanel.java

@@ -0,0 +1,112 @@
+package ui.view.holarchy;
+
+import java.awt.Color;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.Set;
+
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.JScrollPane;
+
+import classes.Holon;
+import ui.controller.Control;
+
+public class HolonInfoPanel extends JPanel {
+
+	Control control;
+	int offset;
+	HolarchyWindow parentFrame;
+	Holon h = null;
+	//name, state, parent, children, virtualNeihgbors, physicalNeighbors
+	JPanel[] panels = { new JPanel(), new JPanel(), new JPanel()};
+	JLabel[] labels1 = {new JLabel("Name: "), new JLabel("UUID"), new JLabel("State: "), new JLabel("Parent: ")};
+	String[] labels2 = {"Subholons", "Virtual neighbors", "Physical neighbors"};
+	Set<JLabel> toRemove = new HashSet();
+	
+	public HolonInfoPanel(HolarchyWindow parentFrame, Control control) {
+		this.control = control;
+		this.parentFrame = parentFrame;
+
+		this.setBounds(0, 0, parentFrame.getWidth()*1/5-1, parentFrame.getHeight());
+		this.setBounds(0, 0, parentFrame.getWidth()*1/5-1, parentFrame.getHeight());
+		this.offset = parentFrame.getWidth()*4/5+1;
+		this.setLayout(null);
+		this.setVisible(true);
+		this.setBackground(Color.white);
+		
+		for(int i=0; i<this.labels1.length; i++) {
+			this.labels1[i].setBounds(5, 5+i*21, this.getWidth(), 20);
+			this.add(this.labels1[i]);
+		}
+		for(int i=0; i<this.panels.length; i++) {
+			JPanel p = this.panels[i];
+			p.setBounds(5, 89+21*i, this.getWidth(), 20);
+			JLabel label = new JLabel(this.labels2[i]);
+			label.setBounds(0, 0, p.getWidth(), p.getHeight());
+			p.add(label);
+			this.add(p);
+		}
+	}
+	
+	public void displayInfos(Holon h) {
+		clearInfos();
+		this.h = h;
+		this.labels1[0].setText("Name: "+h.name);
+		this.labels1[1].setText("UUID: "+h.getUniqueID());
+		this.labels1[2].setText("State: ");
+		this.labels1[3].setText("Superholon: "+(h.getParent() != null ? h.getParent().name : ""));
+		
+		int offset = 110;
+		for(int i=0; i<h.childHolons.size(); i++) {
+			Holon c = h.childHolons.get(i);
+			JLabel l = new JLabel(c.name+"   "+c.getUniqueID());
+			l.setBounds(5,  offset, this.getWidth(), 20);
+			this.add(l);
+			this.toRemove.add(l);
+			offset += 21;
+		}
+		
+		//display virtual neighbors
+		this.panels[1].setLocation(5, offset);
+		offset += 21;
+		ArrayList<String> holons = h.holonControlUnit.getHierarchyController().getVirtualNeighbors();
+//		System.out.println("Holon: "+h.name+" virtual neighbors: "+holons.toString());
+		for(String s : holons) {
+//			System.out.println("id: "+s);
+			Holon c = this.control.getModel().getHolonsByID().get(s);
+			JLabel l = new JLabel(c.name+"   "+c.getUniqueID());
+			l.setBounds(5,  offset, this.getWidth(), 20);
+			this.add(l);
+			this.toRemove.add(l);
+			offset += 21;
+		}
+		
+		//display physical neighbors
+		this.panels[2].setLocation(5, offset);
+		offset += 21;
+		holons = h.holonControlUnit.getHierarchyController().getPhysicalNeighbors();
+		for(String s : holons) {
+			Holon c = this.control.getModel().getHolonsByID().get(s);
+			JLabel l = new JLabel(c.name+"   "+c.getUniqueID());
+			l.setBounds(5,  offset, this.getWidth(), 20);
+			this.add(l);
+			this.toRemove.add(l);
+			offset += 21;
+		}
+	}
+	
+	public void clearInfos() {
+		this.labels1[0].setText("Name: ");
+		this.labels1[1].setText("State: ");
+		this.labels1[2].setText("Superholon: ");
+		for(JLabel l : this.toRemove) {
+			this.remove(l);
+		}
+		for(int i=1; i<this.panels.length; i++) {
+			this.panels[i].setLocation(5, 89+21*i);
+		}
+		this.repaint();
+	}
+	
+}

+ 7 - 3
src/ui/view/outliner/HolonView.java

@@ -35,7 +35,7 @@ import classes.Holon;
 import classes.HolonElement;
 import classes.HolonObject;
 import ui.controller.Control;
-import utility.ImageImport;
+import util.ImageImport;
 /**
  * An Outliner Tab.
  * A high level view on the Model with respect to the Holon Structure. 
@@ -222,7 +222,8 @@ public class HolonView extends JPanel{
      	    	if(info == null) return;
      	    	Holon parent = info.holon.getParent();
      	    	parent.removeChildHolon(info.holon);
-     	    	Holon newHolon = new Holon("New Holon");
+     	    	Holon newHolon = new Holon("New Holon", control.getModel());
+     	    	control.getModel().getHolonsByID().put(newHolon.getUniqueID(), newHolon);
      	    	newHolon.addChild(info.holon);
      	    	parent.addChild(newHolon);
      	    	updateTreeStructure();
@@ -231,7 +232,9 @@ public class HolonView extends JPanel{
     	    	TreePath path = holonTree.getSelectionPath();
     	    	HolonInfo info = getInfoFromPath(path);
     	    	if(info == null) return;
-    	    	info.holon.addChild(new Holon("New Holon"));
+    	    	Holon newHolon = new Holon("New Holon", control.getModel());
+    	    	info.holon.addChild(newHolon);
+     	    	control.getModel().getHolonsByID().put(newHolon.getUniqueID(), newHolon);
     	    	updateTreeStructure();
 	    	});
      	  deleteThisHolon.addActionListener(clicked -> {
@@ -239,6 +242,7 @@ public class HolonView extends JPanel{
   	    	HolonInfo info = getInfoFromPath(path);
   	    	if(info == null) return;
   	    	HolonObject obj = info.holon.getHolonObject();
+ 	    	control.getModel().getHolonsByID().replace(info.holon.getUniqueID(), info.holon);
   	    	if(obj != null) {
   	    		info.holon.reassignAllChildren(info.holon.getParent());
   	    	}else {

+ 2 - 2
src/ui/view/outliner/Outliner.java

@@ -22,8 +22,8 @@ import ui.model.MinimumNetwork;
 import ui.model.Model;
 import ui.model.Passiv;
 import ui.model.Supplier;
-import utility.Event;
-import utility.ImageImport;
+import util.Event;
+import util.ImageImport;
 
 
 

+ 5 - 4
src/ui/view/outliner/TreeUtils.java

@@ -6,7 +6,7 @@ import javax.swing.JTree;
 import javax.swing.tree.DefaultMutableTreeNode;
 import javax.swing.tree.DefaultTreeCellRenderer;
 
-import utility.ImageImport;
+import util.ImageImport;
 
 public class TreeUtils {
 	static void signIconsForTree(JTree tree) {
@@ -23,7 +23,7 @@ public class TreeUtils {
 		}
 	}
 	
-	static void expand(JTree tree) {
+	public static void expand(JTree tree) {
 		for (int i = 0; i < tree.getRowCount(); i++) {
 			tree.expandRow(i);
 		}
@@ -34,10 +34,11 @@ public class TreeUtils {
 	}
 
 	
-	static JScrollPane makePanelFromTree(JTree stateTree) {
+	public static JScrollPane makePanelFromTree(JTree stateTree) {
 		return new JScrollPane(stateTree);
 	}
-	static JScrollPane makeDefaultPanelFromTree(JTree stateTree) {
+	
+	public static JScrollPane makeDefaultPanelFromTree(JTree stateTree) {
 		stateTree.setRootVisible(false);
 		TreeUtils.signIconsForTree(stateTree);
 		TreeUtils.expand(stateTree);