Jelajahi Sumber

Adds SmartDevice type selection to GUI, Adds ChangeDeviceType method

Andreas T. Meyer-Berg 5 tahun lalu
induk
melakukan
988074f69e

+ 753 - 704
src/main/java/de/tu_darmstadt/tk/SmartHomeNetworkSim/control/NetworkController.java

@@ -1,704 +1,753 @@
-package de.tu_darmstadt.tk.SmartHomeNetworkSim.control;
-
-import java.util.Collection;
-import java.util.Iterator;
-import java.util.LinkedList;
-
-import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.Connection;
-import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.Link;
-import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.Model;
-import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.PacketCollector;
-import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.Port;
-import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.Protocol;
-import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.SmartDevice;
-import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.configuration.NetworkTreeNodeStatus;
-
-/**
- * Controller for manipulation of the network model with methods like  
- * 
- *
- * @author Andreas T. Meyer-Berg
- */
-public class NetworkController {
-
-	/**
-	 * Model which will be manipulated
-	 */
-	private Model model;
-	/**
-	 * Controller which can be use
-	 */
-	private Controller controller;
-	/**
-	 * NetworkTreeSettings Controller
-	 */
-	private NetworkTreeSettingsController networkTreeSettings;
-	/**
-	 * Creates a new NetworkController, which may manipulate the given model and use the controller
-	 * @param model Model which can be manipulated
-	 * @param controller main controller for updates etc
-	 */
-	public NetworkController(Model model, Controller controller) {
-		this.model = model;
-		this.controller = controller;
-		networkTreeSettings = controller.getSettingsController().getNetworkTreeSettingsController();
-	}
-
-	/**
-	 * Validate all device positions, move all devices into the bounds, if they are outside the visualization
-	 */
-	public void validateDevicePosition() {
-		// Update all device positions
-		for (SmartDevice d : model.getDevices()) {
-			d.setX(controller.getSettingsController().scalePos(d.getX(), 1.0, controller.getSettingsController().getWidth()));
-			d.setY(controller.getSettingsController().scalePos(d.getY(), 1.0, controller.getSettingsController().getHeight()));
-			d.setZ(controller.getSettingsController().scalePos(d.getZ(), 1.0, controller.getSettingsController().getDepth()));
-		}
-	}
-
-	/**
-	 * Adds SmartDevice to the Model and verifies that it is inside the model
-	 * bounds
-	 * 
-	 * @param sd
-	 *            SmartDevice which should be added to the model
-	 */
-	public void addSmartDevice(SmartDevice sd) {
-		if (model.getDevices().contains(sd))
-			return;
-		model.addDevices(sd);
-		// validate Position
-		sd.setX(controller.getSettingsController().scalePos(sd.getX(), 1.0, controller.getSettingsController().getWidth()));
-		sd.setY(controller.getSettingsController().scalePos(sd.getY(), 1.0, controller.getSettingsController().getHeight()));
-		sd.setZ(controller.getSettingsController().scalePos(sd.getZ(), 1.0, controller.getSettingsController().getDepth()));
-	}
-
-	/**
-	 * Creates a new SmartDevice at the given Position. The Device is moved
-	 * into the model bounds, if the position is outside the bounds
-	 * 
-	 * @param name
-	 *            name of the smartDevice
-	 * @param x_pos
-	 *            position on the x-Axis
-	 * @param y_pos
-	 *            position on the y-Axis
-	 * @param z_pos
-	 *            position on the z-Axis
-	 */
-	public void createSmartDevice(String name, int x_pos, int y_pos, int z_pos) {
-		SmartDevice sd = new SmartDevice(name);
-		sd.setX(controller.getSettingsController().scalePos(x_pos, 1.0, controller.getSettingsController().getWidth()));
-		sd.setY(controller.getSettingsController().scalePos(y_pos, 1.0, controller.getSettingsController().getHeight()));
-		sd.setZ(controller.getSettingsController().scalePos(z_pos, 1.0, controller.getSettingsController().getDepth()));
-		model.addDevices(sd);
-	}
-
-	/**
-	 * Deletes the given SmartDevice toDelete, removes it from its links and
-	 * connections.
-	 * 
-	 * @param toDelete
-	 *            the SmartDevice to delete
-	 */
-	public void deleteSmartDevice(SmartDevice toDelete) {
-		if (toDelete == null)
-			return;
-		// Remove from Collectors
-		PacketCaptureController captureController = controller.getSimulationController().getPacketCaptureController();
-		for(PacketCollector collector:captureController.getPacketCollectors()){
-			if(collector.getDevices().contains(toDelete)){
-				captureController.removeDeviceFromCollector(collector, toDelete);
-			}
-		}
-		
-		// Delete Connections
-		for (Port p : toDelete.getPorts()) {
-			//Skip ports that are not connected
-			if(p.getConnection()==null)
-				continue;
-			removeDeviceFromConnectionAndProtocol(p, p.getConnection());
-		}
-		
-		// Remove from Links
-		LinkedList<Link> links = new LinkedList<Link>(toDelete.getLinks());
-		for (Link link : links)
-			removeSmartDeviceFromLink(toDelete, link);
-		links.clear();
-		// Remove Links from Device
-		toDelete.getLinks().clear();
-				
-		//Remove all ports from the device
-		toDelete.getPorts().clear();
-		
-		//Remove from network Tree
-		networkTreeSettings.removeStatusOfObject(toDelete);
-		model.getDevices().remove(toDelete);
-	}
-	/**
-	 * Returns smartDevices of the model, which are not hidden
-	 * @return all SmartDevices which are not hidden
-	 */
-	public Collection<SmartDevice> getVisibleSmartDevices(){
-		LinkedList<SmartDevice> devices = new LinkedList<SmartDevice>(model.getDevices());
-		devices.removeIf(c->!controller.getSettingsController().getNetworkTreeSettingsController().isVisible(c));
-		return devices;
-	}
-	/**
-	 * Returns smartDevices of the model
-	 * @return all SmartDevices of the model
-	 */
-	public Collection<SmartDevice> getSmartDevices(){
-		return model.getDevices();
-	}
-	/**
-	 * Removes the SmartDevice from the given Link
-	 * 
-	 * @param toRemove the Device that should be removed from the link
-	 * @param link the Link, which contains the SmartDevice
-	 */
-	public void removeSmartDeviceFromLink(SmartDevice toRemove, Link link) {
-		if(link != null){
-			link.removeDevice(toRemove);
-			if(link.getDevices().size()==0)
-				deleteLink(link);
-		}
-		if(toRemove!=null)
-			toRemove.removeLink(link);
-	}
-
-	/**
-	 * Moves the SmartDevice device to the specified location, if it exists
-	 * 
-	 * @param device
-	 *            the device to move
-	 * @param x
-	 *            new x position
-	 * @param y
-	 *            new y position
-	 * @param z
-	 *            new z position
-	 */
-	public void moveSmartDevice(SmartDevice device, int x, int y, int z) {
-		device.setX(x);
-		device.setY(y);
-		device.setZ(z);
-	
-	}
-
-	/**
-	 * Adds Link to the model
-	 * @param link link to add
-	 */
-	public void addLink(Link link){
-		if(link!=null && !model.getConnectionNetworks().contains(link))
-			model.addConnectionNetwork(link);
-	}
-
-	/**
-	 * Removes Link from the Model
-	 * @param link link to remove
-	 */
-	public void removeLink(Link link){
-		model.getConnectionNetworks().remove(link);
-	}
-
-	/**
-	 * Return visible links of the model
-	 * @return visible link
-	 */
-	public Collection<Link> getVisibleLinks(){
-		LinkedList<Link> links = new LinkedList<Link>(model.getConnectionNetworks());
-		links.removeIf(c->!controller.getSettingsController().getNetworkTreeSettingsController().isVisible(c));
-		return links;
-	}
-	
-	/**
-	 * Return links of the model
-	 * @return link
-	 */
-	public Collection<Link> getLinks(){
-		return model.getConnectionNetworks();
-	}
-
-	/**
-	 * Add Connection to the model
-	 * @param connection connection to be added
-	 */
-	public void addConnection(Connection connection){
-		if(connection!=null && !getConnections().contains(connection))
-			model.addConnection(connection);
-	}
-
-	/**
-	 * Remove the connection from the model
-	 * @param connection connection to be removed
-	 */
-	public void removeConnection(Connection connection){
-		model.getConnections().remove(connection);
-	}
-
-	/**
-	 * Returns visible connections of the model
-	 * @return visible connections
-	 */
-	public Collection<Connection> getVisibleConnections(){
-		LinkedList<Connection> links = new LinkedList<Connection>(model.getConnections());
-		links.removeIf(c->!controller.getSettingsController().getNetworkTreeSettingsController().isVisible(c));
-		return links;
-	}
-	
-	/**
-	 * Returns connections of the model
-	 * @return connections
-	 */
-	public Collection<Connection> getConnections(){
-		return model.getConnections();
-	}
-	
-	/**
-	 * Adds the smartDevice to the link
-	 * @param link link to be added to the device
-	 * @param smartDevice device to be added to the link
-	 */
-	public void addLinkToDevice(Link link, SmartDevice smartDevice) {
-		if(link == null || smartDevice == null)return;
-		
-		if(!link.getDevices().contains(smartDevice)){
-			link.addDevice(smartDevice);
-		}
-		
-		if(!smartDevice.getLinks().contains(smartDevice)){
-			smartDevice.addLink(link);
-		}
-		
-	}
-
-	/**
-	 * Remove the smartDevice from the link
-	 * @param link link, the device should be removed from
-	 * @param smartDevice device which should be removed
-	 */
-	public void removeLinkFromDevice(Link link, SmartDevice smartDevice) {
-		if(smartDevice!=null)
-			smartDevice.removeLink(link);
-		if(link!=null){
-			link.removeDevice(smartDevice);
-			if(link.getDevices().size()==0)
-				deleteLink(link);
-		}
-	}
-
-	/**
-	 * Changes Roles of the device to the newRole, returns true, if the role was successfully changed, false if not.
-	 * If false is returned, the device will no longer be part of this connection.
-	 * 
-	 * @param protocol protocol which should be edited
-	 * @param con Connection, which contains the protocol
-	 * @param device device which should be added
-	 * @param newRole new role of the device
-	 * @return true if new role was set, false if not
-	 */
-	public boolean changeRoleOfDevice(Protocol protocol, Connection con, Port device, int newRole){
-		if(newRole < 0 || newRole >= protocol.getNumberOfRoles()){
-			protocol.removeDevice(device);
-			removeDeviceFromConnectionAndProtocol(device, con);
-			return false;
-		} else if(protocol.getDevicesWithRole(newRole).contains(device)){
-			if(!con.getParticipants().contains(device))
-				con.addSmartDevice(device);
-			if(device.getConnection()!=con)
-				device.setConnection(con);
-			return true;
-		}
-		else{
-			protocol.removeDevice(device);
-			boolean added = protocol.addDeviceOfRole(device, newRole);
-			if(added){
-				if(!con.getParticipants().contains(device))
-					con.addSmartDevice(device);
-				if(device.getConnection()!=con)
-					device.setConnection(con);
-				return true;
-			}else{
-				if(con.getParticipants().contains(device))
-					con.removeSmartDevice(device);
-				if(device.getConnection()!=null)
-					device.setConnection(null);
-				return false;
-			}
-		}
-	}
-
-	/**
-	 * Removes Device p from the Connection and Protocol
-	 * @param p Port/Device to remove
-	 * @param connection connection, which should remove the device
-	 */
-	public void removeDeviceFromConnectionAndProtocol(Port p, Connection connection){
-		if(connection != null){
-			connection.removeSmartDevice(p);
-			//TODO: Protocol ?
-			if(connection.getProtocol()!=null){
-				connection.getProtocol().removeDevice(p);
-				if(connection.getParticipants().size() == 0)
-					deleteConnection(connection);
-			}
-		}
-		if(p!=null && p.getConnection() == connection)
-			p.setConnection(null);
-	}
-	
-	/**
-	 * Removes Device p from the Connection and Protocol
-	 * @param p Port/Device to remove
-	 * @param connection connection, which should remove the device
-	 */
-	public void removeDeviceFromConnection(Port p, Connection connection){
-		if(connection != null){
-			connection.removeSmartDevice(p);
-			p.setConnection(null);
-			if(connection.getParticipants().isEmpty())
-				deleteConnection(connection);
-		}
-		if(p != connection)
-			p.setConnection(null);
-	}
-
-	/**
-	 * Adds Device p to the connection with the specified role
-	 * @param p Port/Device to be added
-	 * @param connection Connection
-	 * @param role new role of the device (See {@link Protocol} Roles)
-	 * @return true, if the device was added
-	 */
-	public boolean addDeviceToConnectionAndProtocol(Port p, Connection connection, int role){
-		if(connection.getProtocol().getDevicesWithRole(role).contains(p) || connection.getProtocol().addDeviceOfRole(p, role)){
-			//If port already has the role, or it could be assigned - just check the fields
-			if(!connection.getParticipants().contains(p))
-				connection.addSmartDevice(p);
-			if(p.getConnection()!=connection)
-				p.setConnection(connection);
-			return true;
-		}else {
-			//Device could not be added -> Remove
-			if(p.getConnection()==connection)
-				p.setConnection(null);
-			if(connection.getParticipants().contains(p))
-				connection.removeSmartDevice(p);
-			if(connection.getProtocol().getDevices().contains(p))
-				connection.getProtocol().removeDevice(p);
-			return false;
-		}
-	}
-	
-	/**
-	 * Adds Device p to the connection
-	 * @param p Port/Device to be added
-	 * @param connection Connection
-	 */
-	public void addDeviceToConnection(Port p, Connection connection){
-		if(p==null || connection == null)
-			return;
-		if(!connection.getParticipants().contains(p))
-			connection.addSmartDevice(p);
-		p.setConnection(connection);
-	}
-
-	/**
-	 * Changes the link of the given connection to the new link. Returns true if it was successfully changed, false if it could not be changed.
-	 * @param connection connection which should be edited
-	 * @param link new link
-	 * @return true on successful change, false on failure and restore
-	 */
-	public boolean changeLinkOfConnection(Connection connection, Link link) {
-		if(connection !=null && link != null){
-			addConnectionToLink(connection, link);
-			return true;
-		}else{
-			return false;
-		}
-	}
-
-	/**
-	 * Adds the given connection to the link
-	 * @param connection connection to be added
-	 * @param link link the connection should be added to
-	 */
-	public void addConnectionToLink(Connection connection, Link link) {
-		if(connection == null || link == null)return;
-		/**
-		 * Remove connection from Old Link
-		 */
-		if(connection.getLink()!=null)
-			removeConnectionFromLink(connection, connection.getLink());
-		/**
-		 * Add Connection to new Link
-		 */
-		connection.setLink(link);
-		if(!link.getConnections().contains(connection))
-			link.addConnection(connection);
-		/**
-		 * 
-		 */
-		for(Port p:connection.getParticipants()){
-			if(p!=null && !link.getDevices().contains(p.getOwner())){
-				addLinkToDevice(link, p.getOwner());
-			}
-		}
-	}
-
-	/**
-	 * Changes the type of the connection to the new Type and updates all references
-	 * @param connection connection to be updated
-	 * @param newConnectionClass class of new type
-	 * @return newly created connection
-	 */
-	public Connection changeConnectionType(Connection connection, Class<? extends Connection> newConnectionClass) {
-		
-		Connection newCon = null;
-		try{
-			newCon = newConnectionClass.newInstance();
-			copyNetworkTreeStatus(connection, newCon);
-			newCon.setProtocol(connection.getProtocol());
-			newCon.setStatus(connection.getStatus());
-			newCon.setPacketLossProbability(connection.getPacketLossProbability());
-			newCon.setName(connection.getName());
-			if(getConnections().contains(connection)){
-				removeConnection(connection);
-				addConnection(newCon);	
-			}
-			addConnectionToLink(newCon, connection.getLink());
-			connection.setProtocol(null);
-			for (Iterator<Port> p = connection.getParticipants().iterator(); p.hasNext();) {
-				Port type = (Port) p.next();
-				removeDeviceFromConnection(type, connection);
-				addDeviceToConnection(type, newCon);
-				
-			}
-		}catch(Exception e){
-			System.out.println("Error while changing protocol: "+e.toString());
-			/**
-			 * Restore old connection on Failure
-			 */
-			if(newCon != null){
-				if(getConnections().contains(newCon)){
-					removeConnection(newCon);
-					addConnection(connection);	
-				}
-				if(newCon.getProtocol()!=null){
-					connection.setProtocol(newCon.getProtocol());
-					newCon.setProtocol(null);
-				}
-				if(newCon.getLink()!=null)
-					newCon.getLink().removeConnection(newCon);
-				newCon.setLink(null);
-				for (Iterator<Port> p = connection.getParticipants().iterator(); p.hasNext();) {
-					Port type = (Port) p.next();
-					if(type.getConnection()!=connection)
-						type.setConnection(connection);
-					newCon.removeSmartDevice(type);
-				}
-			}
-			return null;
-		}
-		
-		controller.getSettingsController().getConfigurationManager().getSelectionModel().clickedConnection.clear();
-		connection.setProtocol(null);
-		deleteConnection(connection);
-		
-		controller.notifyObservers();
-		
-		return newCon;
-	}
-
-	/**
-	 * Deletes the network model, removes all Devices, Connections and Links
-	 */
-	public void deleteNetworkModel(){
-		/**
-		 * Devices which should be deleted
-		 */
-		LinkedList<SmartDevice> devicesToDelete = new LinkedList<SmartDevice>(model.getDevices());
-		for(SmartDevice d: devicesToDelete)
-			deleteSmartDevice(d);
-		devicesToDelete.clear();
-		/**
-		 * Connections which should be deleted
-		 */
-		LinkedList<Connection> connectionsToDelete = new LinkedList<Connection>(model.getConnections());
-		for(Connection c: connectionsToDelete)
-			deleteConnection(c);
-		connectionsToDelete.clear();
-		/**
-		 * Links which should be deleted
-		 */
-		LinkedList<Link> linksToDelete = new LinkedList<Link>(model.getConnectionNetworks());
-		for(Link l: model.getConnectionNetworks())
-			deleteLink(l);
-		linksToDelete.clear();
-		/**
-		 * Update the GUI
-		 */
-		controller.notifyObservers();
-	}
-
-	/**
-	 * Deletes the Connection c and all references
-	 * @param c Connection to be deleted
-	 */
-	public void deleteConnection(Connection c) {
-		if(c == null)
-			return;
-		c.setName("Deleted");
-		LinkedList<Port> ports = new LinkedList<Port>(c.getParticipants());
-		for(Port p:ports)
-			removeDeviceFromConnectionAndProtocol(p, c);
-		ports.clear();
-		removeConnectionFromLink(c, c.getLink());
-		c.setStatus(Connection.TERMINATED);
-		networkTreeSettings.removeStatusOfObject(c);
-		removeConnection(c);
-	}
-
-	/**
-	 * Deletes Link 'toDelete' and all references
-	 * @param toDelete Link to be deleted
-	 */
-	public void deleteLink(Link toDelete) {
-		if(toDelete==null)return;
-		LinkedList<SmartDevice> devices = new LinkedList<SmartDevice>(toDelete.getDevices());
-		for(SmartDevice d : devices)
-			removeLinkFromDevice(toDelete, d);
-		devices.clear();
-		LinkedList<Connection> connections = new LinkedList<Connection>(toDelete.getConnections());
-		for(Connection c:connections)
-			removeConnectionFromLink(c,toDelete);
-		connections.clear();
-		toDelete.getPackets().clear();
-		/**
-		 * Remove Link Color
-		 */
-		controller.getSettingsController().getLinkColors().removeLink(toDelete);
-		networkTreeSettings.removeStatusOfObject(toDelete);
-		/**
-		 * Remove from Collectors
-		 */
-		PacketCaptureController captureController = controller.getSimulationController().getPacketCaptureController();
-		for(PacketCollector collector:captureController.getPacketCollectors()){
-			if(collector.getLinks().contains(toDelete)){
-				captureController.removeLinkFromCollector(collector, toDelete);
-			}
-		}
-		/**
-		 * Remove Link from model
-		 */
-		removeLink(toDelete);
-	}
-
-	/**
-	 * Removes Connection from Link
-	 * @param c Connection to be removed
-	 * @param l Link to be removed
-	 */
-	public void removeConnectionFromLink(Connection c, Link l) {
-		if(c!=null && c.getLink()==l){
-			c.setLink(null);
-		}
-		if(l!=null){
-			l.removeConnection(c);		
-		}
-	}
-
-	/**
-	 * Changes the type of the link to new type, specified by the given Link-class
-	 * @param oldLink oldLink, whose attributes will b copied to the new Link 
-	 * @param newType Type/Class of the new Link
-	 * @return newly created Link, null on failure/error
-	 */
-	public Link changeLinkType(Link oldLink, Class<? extends Link> newType) {
-		if(newType == null)
-			return null;
-		/**
-		 * New Link which was created
-		 */
-		Link newLink = null;
-		try{
-			newLink = newType.newInstance();
-		}catch(Exception e){
-			return null;
-		}
-		if (newLink == null || !(newLink instanceof Link)) {
-			return null;
-		}else {
-			//Update Link Color
-			LinkColorController linkColor = controller.getSettingsController().getLinkColors();
-			linkColor.setColorOfLink(newLink, linkColor.getColorOfLink(oldLink).getRight());
-			copyNetworkTreeStatus(oldLink, newLink);
-			//Update Collectors
-			PacketCaptureController captureController = controller.getSimulationController().getPacketCaptureController();
-			for(PacketCollector collector:captureController.getPacketCollectors()){
-				if(collector.getLinks().contains(oldLink)){
-					captureController.removeLinkFromCollector(collector, oldLink);
-					captureController.addLinkToCollector(collector, newLink);
-				}
-			}
-			// Set old Name
-			newLink.setName(oldLink.getName());
-			
-			// Add to Model
-			if(getLinks().contains(oldLink)){
-				removeLink(oldLink);
-				addLink(newLink);
-			}
-			
-			//Connection to the new Link
-			for(Connection c: new LinkedList<Connection>(oldLink.getConnections())){
-				addConnectionToLink(c, newLink);
-			}
-			// Add devices to the new Link
-			LinkedList<SmartDevice> devices= new LinkedList<>(oldLink.getDevices());
-			for(SmartDevice device:devices){
-				removeLinkFromDevice(oldLink, device);
-				addLinkToDevice(newLink, device);
-			}
-			return newLink;
-		}
-	}
-	
-	/**
-	 * Adds status of the old Object to the new Object
-	 * @param oldObject old object, whose status should be copied
-	 * @param newObject new object, which should get the new status
-	 */
-	private void copyNetworkTreeStatus(Object oldObject, Object newObject){
-		NetworkTreeNodeStatus oldStatus = networkTreeSettings.getStatusOfObject(oldObject);
-		NetworkTreeNodeStatus newStatus = new NetworkTreeNodeStatus(newObject);
-		newStatus.setExpanded(oldStatus.isExpanded());
-		newStatus.setVisible(oldStatus.isVisible());
-		networkTreeSettings.addStatusOfObject(newObject, newStatus);
-	}
-	
-	/**
-	 * Changes the Type of the SmartDevice
-	 * @param old old Device which should be 
-	 * @param newClass new Class of the SmartDevice
-	 * @return new SmartDevice, null on failure
-	 */
-	public SmartDevice changeDeviceType(SmartDevice old, Class<? extends SmartDevice> newClass){
-		//Compile new SmartDevice
-		SmartDevice newDevice = old;
-		//Update Packet Collectors
-		PacketCaptureController captureController = controller.getSimulationController().getPacketCaptureController();
-		for(PacketCollector collector:captureController.getPacketCollectors()){
-			if(collector.getDevices().contains(old)){
-				captureController.removeDeviceFromCollector(collector, newDevice);
-				captureController.addDeviceToCollector(collector, newDevice);
-			}
-		}
-		//Update all references
-		
-		//Update Colors tree status ?
-		return newDevice;
-	}
-}
+package de.tu_darmstadt.tk.SmartHomeNetworkSim.control;
+
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.LinkedList;
+
+import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.Connection;
+import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.Link;
+import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.Model;
+import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.PacketCollector;
+import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.Port;
+import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.Protocol;
+import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.SmartDevice;
+import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.configuration.NetworkTreeNodeStatus;
+import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.configuration.SelectionModel;
+
+/**
+ * Controller for manipulation of the network model with methods like  
+ * 
+ *
+ * @author Andreas T. Meyer-Berg
+ */
+public class NetworkController {
+
+	/**
+	 * Model which will be manipulated
+	 */
+	private Model model;
+	/**
+	 * Controller which can be use
+	 */
+	private Controller controller;
+	/**
+	 * NetworkTreeSettings Controller
+	 */
+	private NetworkTreeSettingsController networkTreeSettings;
+	/**
+	 * Creates a new NetworkController, which may manipulate the given model and use the controller
+	 * @param model Model which can be manipulated
+	 * @param controller main controller for updates etc
+	 */
+	public NetworkController(Model model, Controller controller) {
+		this.model = model;
+		this.controller = controller;
+		networkTreeSettings = controller.getSettingsController().getNetworkTreeSettingsController();
+	}
+
+	/**
+	 * Validate all device positions, move all devices into the bounds, if they are outside the visualization
+	 */
+	public void validateDevicePosition() {
+		// Update all device positions
+		for (SmartDevice d : model.getDevices()) {
+			d.setX(controller.getSettingsController().scalePos(d.getX(), 1.0, controller.getSettingsController().getWidth()));
+			d.setY(controller.getSettingsController().scalePos(d.getY(), 1.0, controller.getSettingsController().getHeight()));
+			d.setZ(controller.getSettingsController().scalePos(d.getZ(), 1.0, controller.getSettingsController().getDepth()));
+		}
+	}
+
+	/**
+	 * Adds SmartDevice to the Model and verifies that it is inside the model
+	 * bounds
+	 * 
+	 * @param sd
+	 *            SmartDevice which should be added to the model
+	 */
+	public void addSmartDevice(SmartDevice sd) {
+		if (model.getDevices().contains(sd))
+			return;
+		model.addDevices(sd);
+		// validate Position
+		sd.setX(controller.getSettingsController().scalePos(sd.getX(), 1.0, controller.getSettingsController().getWidth()));
+		sd.setY(controller.getSettingsController().scalePos(sd.getY(), 1.0, controller.getSettingsController().getHeight()));
+		sd.setZ(controller.getSettingsController().scalePos(sd.getZ(), 1.0, controller.getSettingsController().getDepth()));
+	}
+
+	/**
+	 * Creates a new SmartDevice at the given Position. The Device is moved
+	 * into the model bounds, if the position is outside the bounds
+	 * 
+	 * @param name
+	 *            name of the smartDevice
+	 * @param x_pos
+	 *            position on the x-Axis
+	 * @param y_pos
+	 *            position on the y-Axis
+	 * @param z_pos
+	 *            position on the z-Axis
+	 */
+	public void createSmartDevice(String name, int x_pos, int y_pos, int z_pos) {
+		SmartDevice sd = new SmartDevice(name);
+		sd.setX(controller.getSettingsController().scalePos(x_pos, 1.0, controller.getSettingsController().getWidth()));
+		sd.setY(controller.getSettingsController().scalePos(y_pos, 1.0, controller.getSettingsController().getHeight()));
+		sd.setZ(controller.getSettingsController().scalePos(z_pos, 1.0, controller.getSettingsController().getDepth()));
+		model.addDevices(sd);
+	}
+
+	/**
+	 * Deletes the given SmartDevice toDelete, removes it from its links and
+	 * connections.
+	 * 
+	 * @param toDelete
+	 *            the SmartDevice to delete
+	 */
+	public void deleteSmartDevice(SmartDevice toDelete) {
+		if (toDelete == null)
+			return;
+		// Remove from Collectors
+		PacketCaptureController captureController = controller.getSimulationController().getPacketCaptureController();
+		for(PacketCollector collector:captureController.getPacketCollectors()){
+			if(collector.getDevices().contains(toDelete)){
+				captureController.removeDeviceFromCollector(collector, toDelete);
+			}
+		}
+		
+		// Delete Connections
+		for (Port p : toDelete.getPorts()) {
+			//Skip ports that are not connected
+			if(p.getConnection()==null)
+				continue;
+			removeDeviceFromConnectionAndProtocol(p, p.getConnection());
+		}
+		
+		// Remove from Links
+		LinkedList<Link> links = new LinkedList<Link>(toDelete.getLinks());
+		for (Link link : links)
+			removeSmartDeviceFromLink(toDelete, link);
+		links.clear();
+		// Remove Links from Device
+		toDelete.getLinks().clear();
+				
+		//Remove all ports from the device
+		toDelete.getPorts().clear();
+		
+		//Remove from network Tree
+		networkTreeSettings.removeStatusOfObject(toDelete);
+		model.getDevices().remove(toDelete);
+	}
+	/**
+	 * Returns smartDevices of the model, which are not hidden
+	 * @return all SmartDevices which are not hidden
+	 */
+	public Collection<SmartDevice> getVisibleSmartDevices(){
+		LinkedList<SmartDevice> devices = new LinkedList<SmartDevice>(model.getDevices());
+		devices.removeIf(c->!controller.getSettingsController().getNetworkTreeSettingsController().isVisible(c));
+		return devices;
+	}
+	/**
+	 * Returns smartDevices of the model
+	 * @return all SmartDevices of the model
+	 */
+	public Collection<SmartDevice> getSmartDevices(){
+		return model.getDevices();
+	}
+	/**
+	 * Removes the SmartDevice from the given Link
+	 * 
+	 * @param toRemove the Device that should be removed from the link
+	 * @param link the Link, which contains the SmartDevice
+	 */
+	public void removeSmartDeviceFromLink(SmartDevice toRemove, Link link) {
+		if(link != null){
+			link.removeDevice(toRemove);
+			if(link.getDevices().size()==0)
+				deleteLink(link);
+		}
+		if(toRemove!=null)
+			toRemove.removeLink(link);
+	}
+
+	/**
+	 * Moves the SmartDevice device to the specified location, if it exists
+	 * 
+	 * @param device
+	 *            the device to move
+	 * @param x
+	 *            new x position
+	 * @param y
+	 *            new y position
+	 * @param z
+	 *            new z position
+	 */
+	public void moveSmartDevice(SmartDevice device, int x, int y, int z) {
+		device.setX(x);
+		device.setY(y);
+		device.setZ(z);
+	
+	}
+
+	/**
+	 * Adds Link to the model
+	 * @param link link to add
+	 */
+	public void addLink(Link link){
+		if(link!=null && !model.getConnectionNetworks().contains(link))
+			model.addConnectionNetwork(link);
+	}
+
+	/**
+	 * Removes Link from the Model
+	 * @param link link to remove
+	 */
+	public void removeLink(Link link){
+		model.getConnectionNetworks().remove(link);
+	}
+
+	/**
+	 * Return visible links of the model
+	 * @return visible link
+	 */
+	public Collection<Link> getVisibleLinks(){
+		LinkedList<Link> links = new LinkedList<Link>(model.getConnectionNetworks());
+		links.removeIf(c->!controller.getSettingsController().getNetworkTreeSettingsController().isVisible(c));
+		return links;
+	}
+	
+	/**
+	 * Return links of the model
+	 * @return link
+	 */
+	public Collection<Link> getLinks(){
+		return model.getConnectionNetworks();
+	}
+
+	/**
+	 * Add Connection to the model
+	 * @param connection connection to be added
+	 */
+	public void addConnection(Connection connection){
+		if(connection!=null && !getConnections().contains(connection))
+			model.addConnection(connection);
+	}
+
+	/**
+	 * Remove the connection from the model
+	 * @param connection connection to be removed
+	 */
+	public void removeConnection(Connection connection){
+		model.getConnections().remove(connection);
+	}
+
+	/**
+	 * Returns visible connections of the model
+	 * @return visible connections
+	 */
+	public Collection<Connection> getVisibleConnections(){
+		LinkedList<Connection> links = new LinkedList<Connection>(model.getConnections());
+		links.removeIf(c->!controller.getSettingsController().getNetworkTreeSettingsController().isVisible(c));
+		return links;
+	}
+	
+	/**
+	 * Returns connections of the model
+	 * @return connections
+	 */
+	public Collection<Connection> getConnections(){
+		return model.getConnections();
+	}
+	
+	/**
+	 * Adds the smartDevice to the link
+	 * @param link link to be added to the device
+	 * @param smartDevice device to be added to the link
+	 */
+	public void addLinkToDevice(Link link, SmartDevice smartDevice) {
+		if(link == null || smartDevice == null)return;
+		
+		if(!link.getDevices().contains(smartDevice)){
+			link.addDevice(smartDevice);
+		}
+		
+		if(!smartDevice.getLinks().contains(smartDevice)){
+			smartDevice.addLink(link);
+		}
+		
+	}
+
+	/**
+	 * Remove the smartDevice from the link
+	 * @param link link, the device should be removed from
+	 * @param smartDevice device which should be removed
+	 */
+	public void removeLinkFromDevice(Link link, SmartDevice smartDevice) {
+		if(smartDevice!=null)
+			smartDevice.removeLink(link);
+		if(link!=null){
+			link.removeDevice(smartDevice);
+			if(link.getDevices().size()==0)
+				deleteLink(link);
+		}
+	}
+
+	/**
+	 * Changes Roles of the device to the newRole, returns true, if the role was successfully changed, false if not.
+	 * If false is returned, the device will no longer be part of this connection.
+	 * 
+	 * @param protocol protocol which should be edited
+	 * @param con Connection, which contains the protocol
+	 * @param device device which should be added
+	 * @param newRole new role of the device
+	 * @return true if new role was set, false if not
+	 */
+	public boolean changeRoleOfDevice(Protocol protocol, Connection con, Port device, int newRole){
+		if(newRole < 0 || newRole >= protocol.getNumberOfRoles()){
+			protocol.removeDevice(device);
+			removeDeviceFromConnectionAndProtocol(device, con);
+			return false;
+		} else if(protocol.getDevicesWithRole(newRole).contains(device)){
+			if(!con.getParticipants().contains(device))
+				con.addSmartDevice(device);
+			if(device.getConnection()!=con)
+				device.setConnection(con);
+			return true;
+		}
+		else{
+			protocol.removeDevice(device);
+			boolean added = protocol.addDeviceOfRole(device, newRole);
+			if(added){
+				if(!con.getParticipants().contains(device))
+					con.addSmartDevice(device);
+				if(device.getConnection()!=con)
+					device.setConnection(con);
+				return true;
+			}else{
+				if(con.getParticipants().contains(device))
+					con.removeSmartDevice(device);
+				if(device.getConnection()!=null)
+					device.setConnection(null);
+				return false;
+			}
+		}
+	}
+
+	/**
+	 * Removes Device p from the Connection and Protocol
+	 * @param p Port/Device to remove
+	 * @param connection connection, which should remove the device
+	 */
+	public void removeDeviceFromConnectionAndProtocol(Port p, Connection connection){
+		if(connection != null){
+			connection.removeSmartDevice(p);
+			//TODO: Protocol ?
+			if(connection.getProtocol()!=null){
+				connection.getProtocol().removeDevice(p);
+				if(connection.getParticipants().size() == 0)
+					deleteConnection(connection);
+			}
+		}
+		if(p!=null && p.getConnection() == connection)
+			p.setConnection(null);
+	}
+	
+	/**
+	 * Removes Device p from the Connection and Protocol
+	 * @param p Port/Device to remove
+	 * @param connection connection, which should remove the device
+	 */
+	public void removeDeviceFromConnection(Port p, Connection connection){
+		if(connection != null){
+			connection.removeSmartDevice(p);
+			p.setConnection(null);
+			if(connection.getParticipants().isEmpty())
+				deleteConnection(connection);
+		}
+		if(p != connection)
+			p.setConnection(null);
+	}
+
+	/**
+	 * Adds Device p to the connection with the specified role
+	 * @param p Port/Device to be added
+	 * @param connection Connection
+	 * @param role new role of the device (See {@link Protocol} Roles)
+	 * @return true, if the device was added
+	 */
+	public boolean addDeviceToConnectionAndProtocol(Port p, Connection connection, int role){
+		if(connection.getProtocol().getDevicesWithRole(role).contains(p) || connection.getProtocol().addDeviceOfRole(p, role)){
+			//If port already has the role, or it could be assigned - just check the fields
+			if(!connection.getParticipants().contains(p))
+				connection.addSmartDevice(p);
+			if(p.getConnection()!=connection)
+				p.setConnection(connection);
+			return true;
+		}else {
+			//Device could not be added -> Remove
+			if(p.getConnection()==connection)
+				p.setConnection(null);
+			if(connection.getParticipants().contains(p))
+				connection.removeSmartDevice(p);
+			if(connection.getProtocol().getDevices().contains(p))
+				connection.getProtocol().removeDevice(p);
+			return false;
+		}
+	}
+	
+	/**
+	 * Adds Device p to the connection
+	 * @param p Port/Device to be added
+	 * @param connection Connection
+	 */
+	public void addDeviceToConnection(Port p, Connection connection){
+		if(p==null || connection == null)
+			return;
+		if(!connection.getParticipants().contains(p))
+			connection.addSmartDevice(p);
+		p.setConnection(connection);
+	}
+
+	/**
+	 * Changes the link of the given connection to the new link. Returns true if it was successfully changed, false if it could not be changed.
+	 * @param connection connection which should be edited
+	 * @param link new link
+	 * @return true on successful change, false on failure and restore
+	 */
+	public boolean changeLinkOfConnection(Connection connection, Link link) {
+		if(connection !=null && link != null){
+			addConnectionToLink(connection, link);
+			return true;
+		}else{
+			return false;
+		}
+	}
+
+	/**
+	 * Adds the given connection to the link
+	 * @param connection connection to be added
+	 * @param link link the connection should be added to
+	 */
+	public void addConnectionToLink(Connection connection, Link link) {
+		if(connection == null || link == null)return;
+		/**
+		 * Remove connection from Old Link
+		 */
+		if(connection.getLink()!=null)
+			removeConnectionFromLink(connection, connection.getLink());
+		/**
+		 * Add Connection to new Link
+		 */
+		connection.setLink(link);
+		if(!link.getConnections().contains(connection))
+			link.addConnection(connection);
+		/**
+		 * 
+		 */
+		for(Port p:connection.getParticipants()){
+			if(p!=null && !link.getDevices().contains(p.getOwner())){
+				addLinkToDevice(link, p.getOwner());
+			}
+		}
+	}
+
+	/**
+	 * Changes the type of the connection to the new Type and updates all references
+	 * @param connection connection to be updated
+	 * @param newConnectionClass class of new type
+	 * @return newly created connection
+	 */
+	public Connection changeConnectionType(Connection connection, Class<? extends Connection> newConnectionClass) {
+		
+		Connection newCon = null;
+		try{
+			newCon = newConnectionClass.newInstance();
+			copyNetworkTreeStatus(connection, newCon);
+			newCon.setProtocol(connection.getProtocol());
+			newCon.setStatus(connection.getStatus());
+			newCon.setPacketLossProbability(connection.getPacketLossProbability());
+			newCon.setName(connection.getName());
+			if(getConnections().contains(connection)){
+				removeConnection(connection);
+				addConnection(newCon);	
+			}
+			addConnectionToLink(newCon, connection.getLink());
+			connection.setProtocol(null);
+			for (Iterator<Port> p = connection.getParticipants().iterator(); p.hasNext();) {
+				Port type = (Port) p.next();
+				removeDeviceFromConnection(type, connection);
+				addDeviceToConnection(type, newCon);
+				
+			}
+		}catch(Exception e){
+			System.out.println("Error while changing protocol: "+e.toString());
+			/**
+			 * Restore old connection on Failure
+			 */
+			if(newCon != null){
+				if(getConnections().contains(newCon)){
+					removeConnection(newCon);
+					addConnection(connection);	
+				}
+				if(newCon.getProtocol()!=null){
+					connection.setProtocol(newCon.getProtocol());
+					newCon.setProtocol(null);
+				}
+				if(newCon.getLink()!=null)
+					newCon.getLink().removeConnection(newCon);
+				newCon.setLink(null);
+				for (Iterator<Port> p = connection.getParticipants().iterator(); p.hasNext();) {
+					Port type = (Port) p.next();
+					if(type.getConnection()!=connection)
+						type.setConnection(connection);
+					newCon.removeSmartDevice(type);
+				}
+			}
+			return null;
+		}
+		
+		controller.getSettingsController().getConfigurationManager().getSelectionModel().clickedConnection.clear();
+		connection.setProtocol(null);
+		deleteConnection(connection);
+		
+		controller.notifyObservers();
+		
+		return newCon;
+	}
+
+	/**
+	 * Deletes the network model, removes all Devices, Connections and Links
+	 */
+	public void deleteNetworkModel(){
+		/**
+		 * Devices which should be deleted
+		 */
+		LinkedList<SmartDevice> devicesToDelete = new LinkedList<SmartDevice>(model.getDevices());
+		for(SmartDevice d: devicesToDelete)
+			deleteSmartDevice(d);
+		devicesToDelete.clear();
+		/**
+		 * Connections which should be deleted
+		 */
+		LinkedList<Connection> connectionsToDelete = new LinkedList<Connection>(model.getConnections());
+		for(Connection c: connectionsToDelete)
+			deleteConnection(c);
+		connectionsToDelete.clear();
+		/**
+		 * Links which should be deleted
+		 */
+		LinkedList<Link> linksToDelete = new LinkedList<Link>(model.getConnectionNetworks());
+		for(Link l: model.getConnectionNetworks())
+			deleteLink(l);
+		linksToDelete.clear();
+		/**
+		 * Update the GUI
+		 */
+		controller.notifyObservers();
+	}
+
+	/**
+	 * Deletes the Connection c and all references
+	 * @param c Connection to be deleted
+	 */
+	public void deleteConnection(Connection c) {
+		if(c == null)
+			return;
+		c.setName("Deleted");
+		LinkedList<Port> ports = new LinkedList<Port>(c.getParticipants());
+		for(Port p:ports)
+			removeDeviceFromConnectionAndProtocol(p, c);
+		ports.clear();
+		removeConnectionFromLink(c, c.getLink());
+		c.setStatus(Connection.TERMINATED);
+		networkTreeSettings.removeStatusOfObject(c);
+		removeConnection(c);
+	}
+
+	/**
+	 * Deletes Link 'toDelete' and all references
+	 * @param toDelete Link to be deleted
+	 */
+	public void deleteLink(Link toDelete) {
+		if(toDelete==null)return;
+		LinkedList<SmartDevice> devices = new LinkedList<SmartDevice>(toDelete.getDevices());
+		for(SmartDevice d : devices)
+			removeLinkFromDevice(toDelete, d);
+		devices.clear();
+		LinkedList<Connection> connections = new LinkedList<Connection>(toDelete.getConnections());
+		for(Connection c:connections)
+			removeConnectionFromLink(c,toDelete);
+		connections.clear();
+		toDelete.getPackets().clear();
+		/**
+		 * Remove Link Color
+		 */
+		controller.getSettingsController().getLinkColors().removeLink(toDelete);
+		networkTreeSettings.removeStatusOfObject(toDelete);
+		/**
+		 * Remove from Collectors
+		 */
+		PacketCaptureController captureController = controller.getSimulationController().getPacketCaptureController();
+		for(PacketCollector collector:captureController.getPacketCollectors()){
+			if(collector.getLinks().contains(toDelete)){
+				captureController.removeLinkFromCollector(collector, toDelete);
+			}
+		}
+		/**
+		 * Remove Link from model
+		 */
+		removeLink(toDelete);
+	}
+
+	/**
+	 * Removes Connection from Link
+	 * @param c Connection to be removed
+	 * @param l Link to be removed
+	 */
+	public void removeConnectionFromLink(Connection c, Link l) {
+		if(c!=null && c.getLink()==l){
+			c.setLink(null);
+		}
+		if(l!=null){
+			l.removeConnection(c);		
+		}
+	}
+
+	/**
+	 * Changes the type of the link to new type, specified by the given Link-class
+	 * @param oldLink oldLink, whose attributes will b copied to the new Link 
+	 * @param newType Type/Class of the new Link
+	 * @return newly created Link, null on failure/error
+	 */
+	public Link changeLinkType(Link oldLink, Class<? extends Link> newType) {
+		if(newType == null)
+			return null;
+		/**
+		 * New Link which was created
+		 */
+		Link newLink = null;
+		try{
+			newLink = newType.newInstance();
+		}catch(Exception e){
+			return null;
+		}
+		if (newLink == null || !(newLink instanceof Link)) {
+			return null;
+		}else {
+			//Update Link Color
+			LinkColorController linkColor = controller.getSettingsController().getLinkColors();
+			linkColor.setColorOfLink(newLink, linkColor.getColorOfLink(oldLink).getRight());
+			copyNetworkTreeStatus(oldLink, newLink);
+			//Update Collectors
+			PacketCaptureController captureController = controller.getSimulationController().getPacketCaptureController();
+			for(PacketCollector collector:captureController.getPacketCollectors()){
+				if(collector.getLinks().contains(oldLink)){
+					captureController.removeLinkFromCollector(collector, oldLink);
+					captureController.addLinkToCollector(collector, newLink);
+				}
+			}
+			// Set old Name
+			newLink.setName(oldLink.getName());
+			
+			// Add to Model
+			if(getLinks().contains(oldLink)){
+				removeLink(oldLink);
+				addLink(newLink);
+			}
+			
+			//Connection to the new Link
+			for(Connection c: new LinkedList<Connection>(oldLink.getConnections())){
+				addConnectionToLink(c, newLink);
+			}
+			// Add devices to the new Link
+			LinkedList<SmartDevice> devices= new LinkedList<>(oldLink.getDevices());
+			for(SmartDevice device:devices){
+				removeLinkFromDevice(oldLink, device);
+				addLinkToDevice(newLink, device);
+			}
+			return newLink;
+		}
+	}
+	
+	/**
+	 * Adds status of the old Object to the new Object
+	 * @param oldObject old object, whose status should be copied
+	 * @param newObject new object, which should get the new status
+	 */
+	private void copyNetworkTreeStatus(Object oldObject, Object newObject){
+		NetworkTreeNodeStatus oldStatus = networkTreeSettings.getStatusOfObject(oldObject);
+		NetworkTreeNodeStatus newStatus = new NetworkTreeNodeStatus(newObject);
+		newStatus.setExpanded(oldStatus.isExpanded());
+		newStatus.setVisible(oldStatus.isVisible());
+		networkTreeSettings.addStatusOfObject(newObject, newStatus);
+	}
+	
+	/**
+	 * Changes the Type of the SmartDevice
+	 * @param old old Device which should be 
+	 * @param newClass new Class of the SmartDevice
+	 * @return new SmartDevice, null on failure
+	 */
+	public SmartDevice changeDeviceType(SmartDevice old, Class<? extends SmartDevice> newClass){
+		//Compile new SmartDevice
+		if(newClass == null)
+			return null;
+		/**
+		 * New Link which was created
+		 */
+		SmartDevice newDevice = null;
+		try{
+			newDevice = newClass.newInstance();
+		}catch(Exception e){
+			return null;
+		}
+		if (newDevice == null || !(newDevice instanceof SmartDevice)) {
+			return null;
+		}else {
+			// Update base informations
+			newDevice.setName(old.getName());
+			old.setName("Deleted");
+			newDevice.setX(old.getX());
+			newDevice.setY(old.getY());
+			newDevice.setZ(old.getZ());
+			
+			//Update Packet Collectors
+			PacketCaptureController captureController = controller.getSimulationController().getPacketCaptureController();
+			for(PacketCollector collector:captureController.getPacketCollectors()){
+				if(collector.getDevices().contains(old)){
+					captureController.removeDeviceFromCollector(collector, newDevice);
+					captureController.addDeviceToCollector(collector, newDevice);
+				}
+			}
+			
+			//Update all references
+			LinkedList<Link> links = new LinkedList<Link>(old.getLinks());
+			for(Link l: links){
+				addLinkToDevice(l, newDevice);
+				removeLinkFromDevice(l, old);
+			}
+			LinkedList<Port> ports = new LinkedList<Port>(old.getPorts());
+			for(Port p:ports){
+				p.setOwner(newDevice);
+				newDevice.addPort(p);
+				old.removePort(p);
+			}
+			
+			SelectionModel selectionModel = controller.getSettingsController().getConfigurationManager().getSelectionModel();
+			if(selectionModel.selectedDevices.contains(old)){
+				selectionModel.selectedDevices.add(newDevice);
+				selectionModel.selectedDevices.remove(old);
+			}			
+			if(selectionModel.selectedDevicesDrag.contains(old)){
+				selectionModel.selectedDevicesDrag.add(newDevice);
+				selectionModel.selectedDevicesDrag.remove(old);
+			}
+			
+			//Update Colors tree status ?
+			copyNetworkTreeStatus(old, newDevice);
+			
+			//Remove and add Device
+			deleteSmartDevice(old);
+			addSmartDevice(newDevice);
+			return newDevice;
+		}
+	}
+}

+ 8 - 0
src/main/java/de/tu_darmstadt/tk/SmartHomeNetworkSim/core/configuration/ImportConfiguration.java

@@ -9,6 +9,10 @@ import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.Link;
 import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.PrecisionLink;
 import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.Protocol;
 import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.SmartDevice;
+import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.devices.BoolCollectorDevice;
+import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.devices.BoolSensorDevice;
+import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.devices.FloatCollectorDevice;
+import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.devices.FloatSensorDevice;
 import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.protocols.MQTT_protocol;
 import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.protocols.Ping_protocol;
 import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.simpleImplementation.SimpleLink;
@@ -50,6 +54,10 @@ public class ImportConfiguration {
 		standardLinks.add(PrecisionLink.class);
 		
 		standardSmartDevices.add(SmartDevice.class);
+		standardSmartDevices.add(BoolCollectorDevice.class);
+		standardSmartDevices.add(FloatCollectorDevice.class);
+		standardSmartDevices.add(BoolSensorDevice.class);
+		standardSmartDevices.add(FloatSensorDevice.class);
 		
 		standardConnections.add(ConnectionPerformance.class);
 		standardConnections.add(ConnectionPrecision.class);

+ 117 - 53
src/main/java/de/tu_darmstadt/tk/SmartHomeNetworkSim/view/popups/SmartDeviceCreationPopUp.java

@@ -2,13 +2,12 @@ package de.tu_darmstadt.tk.SmartHomeNetworkSim.view.popups;
 
 import java.awt.BorderLayout;
 import java.awt.Color;
-import java.awt.GridBagLayout;
-import java.awt.GridBagConstraints;
-import java.awt.Insets;
+import java.util.LinkedList;
 
 import javax.swing.JButton;
 import javax.swing.JDialog;
 import javax.swing.JLabel;
+import javax.swing.JOptionPane;
 import javax.swing.JPanel;
 import javax.swing.JTabbedPane;
 import javax.swing.JTextField;
@@ -17,6 +16,8 @@ import de.tu_darmstadt.tk.SmartHomeNetworkSim.control.Controller;
 import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.SmartDevice;
 import de.tu_darmstadt.tk.SmartHomeNetworkSim.view.util.IntegerInputValidator;
 
+import javax.swing.JComboBox;
+
 @SuppressWarnings("serial")
 /**
  * PopUp for Creation of SmartDevices, which allows configuration of a new
@@ -44,7 +45,7 @@ public class SmartDeviceCreationPopUp extends JDialog {
 	/**
 	 * Controller which adds the new Device to the model
 	 */
-	private Controller c;
+	private Controller controller;
 	/**
 	 * Width of the model, which is the maximum x-Position
 	 */
@@ -62,7 +63,19 @@ public class SmartDeviceCreationPopUp extends JDialog {
 	 * device should not be added to the controller.
 	 */
 	private boolean edit;
-
+	/**
+	 * Mutex to disable listeners during refresh
+	 */
+	private boolean mutex = false;
+	/**
+	 * Last selected SmartDevice index
+	 */
+	private int lastSmartDeviceIndex = -1;
+	/**
+	 * ComboBox containing the different Device classes
+	 */
+	private JComboBox<String> cmbDevice;
+	
 	/**
 	 * Allows editing/creation of a smartDevice
 	 * 
@@ -77,10 +90,10 @@ public class SmartDeviceCreationPopUp extends JDialog {
 
 		setModal(true);
 		// setType(Type.POPUP); -> Crashes on Linux
-		this.c = control;
-		this.maxX = c.getSettingsController().getWidth();
-		this.maxY = c.getSettingsController().getHeight();
-		this.visualisationRadius = c.getSettingsController().getDeviceVisualizationRadius();
+		this.controller = control;
+		this.maxX = controller.getSettingsController().getWidth();
+		this.maxY = controller.getSettingsController().getHeight();
+		this.visualisationRadius = controller.getSettingsController().getDeviceVisualizationRadius();
 		this.edit = edit;
 		newDevice = deviceToEdit;
 
@@ -95,77 +108,110 @@ public class SmartDeviceCreationPopUp extends JDialog {
 
 		JPanel panelGeneral = new JPanel();
 		tabbedPane.addTab("General", null, panelGeneral, "Edit general Information of the SmartDevice");
-		GridBagLayout gbl_panelGeneral = new GridBagLayout();
-		gbl_panelGeneral.columnWidths = new int[] { 148, 259, 0 };
-		gbl_panelGeneral.rowHeights = new int[] { 22, 22, 0, 0, 0, 0, 0, 0 };
-		gbl_panelGeneral.columnWeights = new double[] { 0.0, 0.0, Double.MIN_VALUE };
-		gbl_panelGeneral.rowWeights = new double[] { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, Double.MIN_VALUE };
-		panelGeneral.setLayout(gbl_panelGeneral);
+		panelGeneral.setLayout(null);
 
 		JLabel lblName = new JLabel("Name:");
+		lblName.setBounds(0, 3, 38, 16);
 		lblName.setToolTipText("Change the name of the SmartDevice");
-		GridBagConstraints gbc_lblName = new GridBagConstraints();
-		gbc_lblName.anchor = GridBagConstraints.WEST;
-		gbc_lblName.insets = new Insets(0, 0, 5, 5);
-		gbc_lblName.gridx = 0;
-		gbc_lblName.gridy = 0;
-		panelGeneral.add(lblName, gbc_lblName);
+		panelGeneral.add(lblName);
 
 		tfName = new JTextField();
+		tfName.setBounds(370, 0, 226, 22);
 		tfName.setToolTipText("Enter the SmartDevice name");
-		GridBagConstraints gbc_tfName = new GridBagConstraints();
-		gbc_tfName.anchor = GridBagConstraints.NORTHWEST;
-		gbc_tfName.insets = new Insets(0, 0, 5, 0);
-		gbc_tfName.gridx = 1;
-		gbc_tfName.gridy = 0;
-		panelGeneral.add(tfName, gbc_tfName);
+		panelGeneral.add(tfName);
 		tfName.setColumns(20);
 		tfName.setText(newDevice.getName());
 
 		JLabel lblXposition = new JLabel(
 				"x-position in [" + visualisationRadius + "," + (maxX - visualisationRadius) + "]:");
+		lblXposition.setBounds(0, 30, 106, 16);
 		lblXposition.setToolTipText("Set the x position, which should be an integer in the given interval.");
-		GridBagConstraints gbc_lblXposition = new GridBagConstraints();
-		gbc_lblXposition.anchor = GridBagConstraints.WEST;
-		gbc_lblXposition.insets = new Insets(0, 0, 5, 5);
-		gbc_lblXposition.gridx = 0;
-		gbc_lblXposition.gridy = 1;
-		panelGeneral.add(lblXposition, gbc_lblXposition);
+		panelGeneral.add(lblXposition);
 
 		tfXposition = new JTextField();
+		tfXposition.setBounds(370, 27, 116, 22);
 		lblXposition.setToolTipText("Enter the x position, which should be an integer in the given interval.");
-		GridBagConstraints gbc_tfXposition = new GridBagConstraints();
-		gbc_tfXposition.anchor = GridBagConstraints.NORTHWEST;
-		gbc_tfXposition.insets = new Insets(0, 0, 5, 0);
-		gbc_tfXposition.gridx = 1;
-		gbc_tfXposition.gridy = 1;
-		panelGeneral.add(tfXposition, gbc_tfXposition);
+		panelGeneral.add(tfXposition);
 		tfXposition.setColumns(10);
 		tfXposition.setText("" + newDevice.getX());
 		tfXposition.setInputVerifier(new IntegerInputValidator(visualisationRadius, maxX - visualisationRadius));
 
 		JLabel lblYposition = new JLabel(
 				"y-position in [" + visualisationRadius + "," + (maxY - visualisationRadius) + "]:");
+		lblYposition.setBounds(0, 57, 106, 16);
 		lblXposition.setToolTipText("Set the y position, which should be an integer in the given interval.");
-		GridBagConstraints gbc_lblYposition = new GridBagConstraints();
-		gbc_lblYposition.anchor = GridBagConstraints.WEST;
-		gbc_lblYposition.insets = new Insets(0, 0, 5, 5);
-		gbc_lblYposition.gridx = 0;
-		gbc_lblYposition.gridy = 2;
-		panelGeneral.add(lblYposition, gbc_lblYposition);
+		panelGeneral.add(lblYposition);
 
 		tfYposition = new JTextField();
+		tfYposition.setBounds(370, 54, 116, 22);
 		tfYposition.setToolTipText("Set the y position, which should be an integer in the given interval.");
-		GridBagConstraints gbc_tfYposition = new GridBagConstraints();
-		gbc_tfYposition.anchor = GridBagConstraints.WEST;
-		gbc_tfYposition.insets = new Insets(0, 0, 5, 0);
-		gbc_tfYposition.gridx = 1;
-		gbc_tfYposition.gridy = 2;
-		panelGeneral.add(tfYposition, gbc_tfYposition);
+		panelGeneral.add(tfYposition);
 		tfYposition.setColumns(10);
 		tfYposition.setText("" + newDevice.getY());
 		tfYposition.setInputVerifier(new IntegerInputValidator(visualisationRadius, maxY - visualisationRadius));
+		
+		
+		
+		
+		
+		cmbDevice = new JComboBox<String>();
+		cmbDevice.setBounds(0, 112, 365, 22);
+		panelGeneral.add(cmbDevice);
+		cmbDevice.addActionListener(a -> {
+			if (mutex) {
+				return;
+			}
+			cmbDevice.getSelectedIndex();
+			int selectedIndex = cmbDevice.getSelectedIndex();
+			if (lastSmartDeviceIndex != selectedIndex && selectedIndex != -1) {
+				SmartDevice importedDevice = controller.getNetworkController().changeDeviceType(newDevice, controller.getImportController().getSmartDevices().get(selectedIndex));
+				if (importedDevice == null) {
+					System.out.println("Warning invalid SmartDevice changed");
+					cmbDevice.setSelectedIndex(lastSmartDeviceIndex);
+				} else {
+					newDevice = importedDevice;
+					lastSmartDeviceIndex = selectedIndex;
+				}
+			} else {
+				cmbDevice.setSelectedIndex(lastSmartDeviceIndex);
+			}
+
+		});
+		
+		
+		
+		
+		JButton btnImportSmartDevice = new JButton("Import Smart Device");
+		btnImportSmartDevice.setBounds(418, 111, 199, 25);
+		panelGeneral.add(btnImportSmartDevice);
+		btnImportSmartDevice.addActionListener(a -> {
+			ImportPopUp<SmartDevice> popUp = new ImportPopUp<SmartDevice>(this, SmartDevice.class);
+			try {
+				Class<? extends SmartDevice> imported = popUp.showPopUp();
+				if (imported == null)
+					return;
+				if (controller.getImportController().addSmartDevice(imported)) {
+					refreshGUI();
+				} else {
+					JOptionPane.showMessageDialog(this, "Import failed: Invalid Connection");
+				}
+			} catch (Exception e1) {
+				JOptionPane.showMessageDialog(this, "Import failed: " + e1.getMessage());
+			}
+		});
+		
+		JTabbedPane tbConfigureDevice = new JTabbedPane(JTabbedPane.TOP);
+		tbConfigureDevice.setBounds(10, 147, 607, 230);
+		panelGeneral.add(tbConfigureDevice);
+		
+		JPanel panel = new JPanel();
+		tbConfigureDevice.addTab("Sensor", null, panel, null);
 
+		
+		
+		/*
+		 * Other Tabs 
+		 */
 		LinkEditorPanel panelLinks = new LinkEditorPanel(newDevice, control);
 		tabbedPane.addTab("Links", null, panelLinks, "Edit Links of the SmartDevice");
 
@@ -186,6 +232,7 @@ public class SmartDeviceCreationPopUp extends JDialog {
 		getContentPane().add(btnCreateDevice, BorderLayout.SOUTH);
 
 		tabbedPane.setSelectedIndex(0);
+		refreshGUI();
 	}
 
 	/**
@@ -237,12 +284,29 @@ public class SmartDeviceCreationPopUp extends JDialog {
 		if (valid) {
 			if (edit == false) {
 				// Add new Device, update Visualization and dispose the PopUp
-				c.getNetworkController().addSmartDevice(newDevice);
+				controller.getNetworkController().addSmartDevice(newDevice);
 
 			}
-			c.notifyObservers();
+			controller.notifyObservers();
 			this.setVisible(false);
 			this.dispose();
 		}
 	}
+	
+	public void refreshGUI(){
+		mutex = true;
+		// Update selected Device Type
+		cmbDevice.removeAllItems();
+		LinkedList<Class<? extends SmartDevice>> availableDevices = controller.getImportController().getSmartDevices();
+		for (Class<? extends SmartDevice> c : availableDevices)
+			cmbDevice.addItem(c.getSimpleName());
+		// Set Index to selected SmartDevice
+		for (int i = 0; i < availableDevices.size(); i++)
+			if (newDevice.getClass().equals(availableDevices.get(i))) {
+				// Select the right Device Type and save last index
+				lastSmartDeviceIndex = i;
+			}
+		cmbDevice.setSelectedIndex(lastSmartDeviceIndex);
+		mutex = false;
+	}
 }