Tom Troppmann пре 2 година
родитељ
комит
182f1e6217

+ 63 - 1
src/classes/Holon.java

@@ -2,18 +2,25 @@ package classes;
 
 import java.util.ArrayList;
 import java.util.Collections;
+import java.util.HashMap;
 import java.util.List;
 
+import ui.controller.Control;
+import ui.model.DecoratedNetwork;
+
 public class Holon {
 	public String name = new String();
 	private Holon parent = null;
 	public ArrayList<Holon> childHolons = new ArrayList<Holon>();
 	private List<HolonElement> elements = new ArrayList<HolonElement>();
+	//HolonObject is the lowest representation of a holon.
+	private HolonObject holonObject;
 	
 	public Holon(String name) {
 		this.name = name;
 	}
 	public Holon(HolonObject object) {
+		holonObject = object;
 		name = object.getName();
 		elements.addAll(object.getElements());
 		for(HolonElement ele : elements) {
@@ -55,6 +62,7 @@ public class Holon {
 		}
 	}
 	
+	
 	public int getChildCount() {
 		return childHolons.size();
 	}
@@ -75,8 +83,9 @@ public class Holon {
 	public String toString() {
 		return name;
 	}
+
+	
 	
-	//TODO This can maybe cached
 	public int getLayer() {
 		return parent != null ? parent.getLayer() +  1 : 0;
 	}
@@ -89,7 +98,60 @@ public class Holon {
 		return cloned;
 	}
 	
+	public boolean checkHolonArePhysicalConnected(Holon other, Control control) {
+		HashMap<HolonObject, DecoratedNetwork> table = control.getSimManager().getActualDecorState().getHolonObjectNetworkTable();
+		HolonObject a = tryGetAPhysicalHolon();
+		HolonObject b = other.tryGetAPhysicalHolon();
+		boolean aHolonIsPureAbstract = a == null || b == null;
+		return  aHolonIsPureAbstract || table.get(a) == table.get(b);
+	}
+	
+	private HolonObject tryGetAPhysicalHolon() {
+		if(holonObject != null) {
+			return holonObject;
+		}
+		for(Holon holon : childHolons) {
+			HolonObject object = holon.tryGetAPhysicalHolon();
+			if(object != null) {
+				return object;
+			}
+		}
+		return null;
+	}
+	
 	
+	public void checkRepairHolarchy(HashMap<HolonObject, DecoratedNetwork> table, Holon stateHolon) {
+		if(childHolons.isEmpty()) {
+			return;
+		}
+		//To establish the invariant that all child holons are repaired
+		for(Holon other : childHolons) {
+			other.checkRepairHolarchy(table, stateHolon);
+		}
+		//Repair this Holon
+		HolonObject first = tryGetAPhysicalHolon();
+		if(first == null) {
+			return;
+		}
+		List<Holon> removeList = new ArrayList<Holon>();
+		for(Holon other : childHolons) {
+			HolonObject otherHolonObject = other.tryGetAPhysicalHolon();
+			boolean isPureAbstract = otherHolonObject == null;
+			if(isPureAbstract) {
+				continue;
+			}
+			boolean isPhysicalConnected = table.get(first) == table.get(otherHolonObject);
+			if(!isPhysicalConnected) {
+				removeList.add(other);
+			}
+		}
+		//Remove holons
+		for(Holon holon : removeList) {
+			holon.removeFromParent();
+			stateHolon.addChild(holon);
+		}
+		
+	}
 	
 }
 

+ 26 - 4
src/ui/controller/SimulationManager.java

@@ -14,9 +14,12 @@ import ui.model.Model;
 import ui.model.Model.FairnessModel;
 import ui.model.VisualRepresentationalState;
 
+import java.lang.ModuleLayer.Controller;
 import java.util.ArrayList;
 import java.util.HashMap;
+import java.util.Iterator;
 import java.util.LinkedList;
+import java.util.List;
 import java.util.ListIterator;
 
 
@@ -117,10 +120,20 @@ public class SimulationManager {
 				}
 			}
 		}
+		//Create lookUpTableForHolonObjetcs
+		
+		
+		
+		
+		HashMap<HolonObject, DecoratedNetwork> holonObjectNetworkTable = new HashMap<HolonObject, DecoratedNetwork>();
 		ArrayList<DecoratedNetwork> decorNetworks = new ArrayList<DecoratedNetwork>();
 		FairnessModel actualFairnessModel = model.getFairnessModel();
 		for (MinimumNetwork net : list) {
-			decorNetworks.add(new DecoratedNetwork(net, timestep, actualFairnessModel, newFlexManager));
+			DecoratedNetwork decNetwork = new DecoratedNetwork(net, timestep, actualFairnessModel, newFlexManager);
+			decorNetworks.add(decNetwork);
+			for(HolonObject obj : net.getHolonObjectList()) {
+				holonObjectNetworkTable.put(obj, decNetwork);
+			}
 		}
 
 		
@@ -132,12 +145,21 @@ public class SimulationManager {
 			leftOverDecoratedCables.add(new DecoratedCable(cable.getModel(), cable.getState(), 0.0f));
 		}
 		ArrayList<DecoratedSwitch> listOfDecoratedSwitches = decorateSwitches(minimumModel, timestep);
-		DecoratedState stateFromThisTimestep = new DecoratedState(decorNetworks, leftOverDecoratedCables, listOfDecoratedSwitches, newFlexManager, timestep);
+		DecoratedState stateFromThisTimestep = new DecoratedState(decorNetworks, leftOverDecoratedCables, listOfDecoratedSwitches, newFlexManager, timestep, holonObjectNetworkTable);
 		saves.put(timestep, stateFromThisTimestep);
 		if(updateVisual)savesVisual.put(timestep, new VisualRepresentationalState(stateFromThisTimestep, minimumModel));
-
-		
+		//Check Holarchy and split Holons if no physical connection is present.
+		List<Holon> holonList = model.getStateHolon().childHolons;
+		for(int i = 0; i < holonList.size(); i++) {
+			holonList.get(i).checkRepairHolarchy(holonObjectNetworkTable, model.getStateHolon());
+		}
 	}
+
+
+
+
+
+
 	/** 
 	 * Decorate a switch
 	 * @param minModel

+ 2 - 0
src/ui/model/DecoratedNetwork.java

@@ -16,9 +16,11 @@ public class DecoratedNetwork {
 	private ArrayList<Consumer> consumerSelfSuppliedList = new ArrayList<Consumer>();
 	private ArrayList<Passiv> passivNoEnergyList = new ArrayList<Passiv>();
 	private ArrayList<DecoratedCable> decoratedCableList = new ArrayList<DecoratedCable>();
+	
 	private int timestep;
 
 	public DecoratedNetwork(MinimumNetwork minimumNetwork, int Iteration, FairnessModel actualFairnessModel, FlexManager flexManager){	
+		
 		this.timestep = Iteration;
 		switch(actualFairnessModel) {
 		case AllEqual:

+ 8 - 1
src/ui/model/DecoratedState.java

@@ -1,7 +1,9 @@
 package ui.model;
 
 import java.util.ArrayList;
+import java.util.HashMap;
 
+import classes.HolonObject;
 import ui.controller.FlexManager;
 
 
@@ -10,13 +12,18 @@ public class DecoratedState {
 	ArrayList<DecoratedNetwork> networkList;
 	ArrayList<DecoratedCable> leftOverEdges;
 	ArrayList<DecoratedSwitch> decoratedSwitches;
+	HashMap<HolonObject, DecoratedNetwork> holonObjectNetworkTable;
 	FlexManager flexManager;
-	public DecoratedState(ArrayList<DecoratedNetwork> networkList, ArrayList<DecoratedCable> leftOverEdges, ArrayList<DecoratedSwitch> decoratedSwitches, FlexManager flexManager , int timestepOfState){
+	public DecoratedState(ArrayList<DecoratedNetwork> networkList, ArrayList<DecoratedCable> leftOverEdges, ArrayList<DecoratedSwitch> decoratedSwitches, FlexManager flexManager , int timestepOfState, HashMap<HolonObject, DecoratedNetwork> holonObjectNetworkTable){
 		this.networkList = networkList;
 		this.leftOverEdges = leftOverEdges;
 		this.decoratedSwitches = decoratedSwitches;
 		this.timestepOfState = timestepOfState;
 		this.flexManager = flexManager;
+		this.holonObjectNetworkTable = holonObjectNetworkTable;
+	}
+	public HashMap<HolonObject, DecoratedNetwork> getHolonObjectNetworkTable() {
+		return holonObjectNetworkTable;
 	}
 	public ArrayList<DecoratedNetwork> getNetworkList() {
 		return networkList;

+ 185 - 25
src/ui/view/outliner/HolonView.java

@@ -1,23 +1,33 @@
 package ui.view.outliner;
 
 import java.awt.BorderLayout;
-import java.awt.Color;
 import java.awt.Component;
+import java.awt.Dimension;
 import java.awt.datatransfer.DataFlavor;
 import java.awt.datatransfer.Transferable;
 import java.awt.datatransfer.UnsupportedFlavorException;
+import java.awt.event.MouseAdapter;
+import java.awt.event.MouseEvent;
 import java.io.IOException;
 
+import javax.swing.AbstractCellEditor;
 import javax.swing.DropMode;
 import javax.swing.Icon;
 import javax.swing.ImageIcon;
+import javax.swing.JCheckBoxMenuItem;
 import javax.swing.JComponent;
+import javax.swing.JLabel;
+import javax.swing.JMenuItem;
 import javax.swing.JPanel;
+import javax.swing.JPopupMenu;
+import javax.swing.JTextField;
 import javax.swing.JTree;
+import javax.swing.SwingUtilities;
 import javax.swing.ToolTipManager;
 import javax.swing.TransferHandler;
 import javax.swing.tree.DefaultMutableTreeNode;
 import javax.swing.tree.DefaultTreeCellRenderer;
+import javax.swing.tree.TreeCellEditor;
 import javax.swing.tree.TreePath;
 import javax.swing.tree.TreeSelectionModel;
 
@@ -33,8 +43,12 @@ import utility.ImageImport;
  */
 public class HolonView extends JPanel{
 	private Control control; 
-	private JTree tree;
+	private JTree holonTree;
 	private DefaultMutableTreeNode root;
+	private boolean showHolonElementsInTree = true;
+	
+	
+	
 	public HolonView(Outliner parent, Control control) {
 		this.control = control;
 		this.setLayout(new BorderLayout());
@@ -43,20 +57,24 @@ public class HolonView extends JPanel{
 	}
 
 	private void initilizePanel() {
-		tree = generateTree();
-		tree.setCellRenderer(new HolonJtreeRenderer());
-		tree.setDragEnabled(true);
-        tree.setDropMode(DropMode.ON_OR_INSERT);
-        tree.setTransferHandler(new HolonTransferHandler());
-        tree.getSelectionModel().setSelectionMode(
+		holonTree = generateTree();
+		holonTree.setCellRenderer(new HolonJtreeRenderer());
+		holonTree.setDragEnabled(true);
+        holonTree.setDropMode(DropMode.ON_OR_INSERT);
+        holonTree.setTransferHandler(new HolonTransferHandler());
+        holonTree.getSelectionModel().setSelectionMode(
                 TreeSelectionModel.SINGLE_TREE_SELECTION);
-        ToolTipManager.sharedInstance().registerComponent(tree);
-        TreeUtils.expand(tree);
-        tree.setRootVisible(true);
-		this.add(TreeUtils.makePanelFromTree(tree));
+        ToolTipManager.sharedInstance().registerComponent(holonTree);
+        TreeUtils.expand(holonTree);
+        holonTree.setRootVisible(true);
+        holonTree.addMouseListener(new HolonMouseListener());
+        holonTree.setEditable(true);
+        holonTree.setCellEditor(new HolonNodeEditor());
+		this.add(TreeUtils.makePanelFromTree(holonTree));
 	}
 	
 	
+
 	private JTree generateTree() {
 		root = generateFromHolon(control.getModel().getStateHolon());
 		return new JTree(root);
@@ -67,28 +85,34 @@ public class HolonView extends JPanel{
 		for(Holon child : holon.getChildView()) {
 			node.add(generateFromHolon(child));
 		}
-		for(HolonElement ele : holon.getElementView()) {
-			node.add(new DefaultMutableTreeNode(new ElementInfo(ele)));
+		if(this.showHolonElementsInTree) {
+			for(HolonElement ele : holon.getElementView()) {
+				node.add(new DefaultMutableTreeNode(new ElementInfo(ele)));
+			}
 		}
 		return node;
 	}
 	private void updateTreeStructure() {
+		holonTree.clearSelection();
 		root.removeAllChildren();
 		Holon holon = control.getModel().getStateHolon();
 		for(Holon child : holon.getChildView()) {
 			root.add(generateFromHolon(child));
 		}
-		for(HolonElement ele : holon.getElementView()) {
-			root.add(new DefaultMutableTreeNode(new ElementInfo(ele)));
+		if(this.showHolonElementsInTree) {
+			for(HolonElement ele : holon.getElementView()) {
+				root.add(new DefaultMutableTreeNode(new ElementInfo(ele)));
+			}
 		}
-		tree.updateUI();
-		TreeUtils.expand(tree);
+		holonTree.updateUI();
+		TreeUtils.expand(holonTree);
 	}
 	
 	interface HolonNode{
 		public Transferable getTransferable(HolonTransferHandler handler);
 		public Icon getIcon(); 
 		public String getToolTip();
+		public void SetName(String name);
 	}
 	static final Icon elementIcon = new ImageIcon(ImageImport.loadImage("/Button_Images/element.png",16,16));
 	static final String elementToolTip = "Element";
@@ -118,6 +142,10 @@ public class HolonView extends JPanel{
 		public String getToolTip() {
 			return elementToolTip;
 		}
+		@Override
+		public void SetName(String name) {
+			element.setEleName(name);
+		}
 	}
 	static final Icon holonIcon = new ImageIcon(ImageImport.loadImage("/Button_Images/holon.png",16,16));
 	static final String holonToolTip = "Holon";
@@ -158,15 +186,95 @@ public class HolonView extends JPanel{
 		public String getToolTip() {
 			return holonToolTip;
 		}
+		@Override
+		public void SetName(String name) {
+			holon.name = name;
+		}
 		
 	}
 	
 	
+	
+	
+	//Context Menu
+	class HolonMouseListener extends MouseAdapter{
+		
+		JPopupMenu menu = new JPopupMenu ();
+		JCheckBoxMenuItem showElements = new JCheckBoxMenuItem("Show Elements"); 
+		JMenuItem newHolonAsParentItem = new JMenuItem("Create new Holon as Parent.");
+ 	    JMenuItem newHolonAsChildItem = new JMenuItem("Create new Holon as Child.");
+		
+		public HolonMouseListener() {
+			//Initialize MenuItems
+            
+     	    showElements.setState(showHolonElementsInTree);
+     	    showElements.addActionListener(clicked -> {
+     	    	showHolonElementsInTree = showElements.getState();
+     	    	updateTreeStructure();
+     	    });
+     	    
+     	    newHolonAsParentItem.addActionListener(clicked -> {
+     	    	TreePath path = holonTree.getSelectionPath();
+     	    	HolonInfo info = getInfoFromPath(path);
+     	    	if(info == null) return;
+     	    	Holon parent = info.holon.getParent();
+     	    	parent.removeChildHolon(info.holon);
+     	    	Holon newHolon = new Holon("New Holon");
+     	    	newHolon.addChild(info.holon);
+     	    	parent.addChild(newHolon);
+     	    	updateTreeStructure();
+ 	    	});
+     	   newHolonAsChildItem.addActionListener(clicked -> {
+    	    	TreePath path = holonTree.getSelectionPath();
+    	    	HolonInfo info = getInfoFromPath(path);
+    	    	if(info == null) return;
+    	    	info.holon.addChild(new Holon("New Holon"));
+    	    	updateTreeStructure();
+	    	});
+     	    
+     	    
+     	    //CreateMenu
+     	    menu.add(showElements);
+     	    menu.addSeparator();
+     	    menu.add(newHolonAsParentItem);
+     	    menu.add(newHolonAsChildItem);
+		}
+		
+		public void mousePressed ( MouseEvent e )
+        {
+            if (!SwingUtilities.isRightMouseButton(e))
+            {
+            	return;
+            }
+            TreePath path = holonTree.getSelectionPath();
+            boolean pathIsViable = (path != null);
+            newHolonAsParentItem.setVisible(pathIsViable);
+            newHolonAsChildItem.setVisible(pathIsViable);
+        	menu.show(holonTree, e.getX(), e.getY());
+        }
+		
+		HolonInfo getInfoFromPath(TreePath path) {
+			if(path == null) {
+ 	    		return null;
+ 	    	}
+ 	    	DefaultMutableTreeNode node = (DefaultMutableTreeNode) path.getLastPathComponent();
+ 	    	if(!(node.getUserObject() instanceof HolonInfo)) {
+ 	    		return null;
+ 	    	}
+ 	    	return (HolonInfo)node.getUserObject();
+		}
+	}
+	
+	
+	//Drag and Drop
+	//Make drag and drop von Holons possible.
+	//Implement HolonElement drag and drop too, but its disabled.
 	class HolonTransferHandler extends TransferHandler{
 		DataFlavor holonFlavor;		
 		DataFlavor[] holonFlavorArray = new DataFlavor[1]; 
 		DataFlavor elementFlavor;
 		DataFlavor[] elementFlavorArray = new DataFlavor[1]; 
+		boolean allowHolonElementDragAndDrop = false;
 		HolonTransferHandler(){
 			try {
 				String mimeType = DataFlavor.javaJVMLocalObjectMimeType +
@@ -211,7 +319,17 @@ public class HolonView extends JPanel{
 		        	return false;
 		        }
 	
-		        return true;
+		        //Check physical connected
+		        try {
+		        	Holon dropHolon = ((HolonInfo) node.getUserObject()).holon;
+					Holon dragHolon = (Holon) support.getTransferable().getTransferData(holonFlavor);
+					boolean physicalConnected = dropHolon.checkHolonArePhysicalConnected(dragHolon, control);
+					boolean isAllStateHolon = dropHolon.getLayer() == 0;
+					return  physicalConnected || isAllStateHolon;
+				} catch (UnsupportedFlavorException | IOException e) {
+					e.printStackTrace();
+					return false;
+				}
 	    }
 		@Override 
 		public boolean importData(TransferHandler.TransferSupport support) {
@@ -255,9 +373,17 @@ public class HolonView extends JPanel{
 	        	DefaultMutableTreeNode node = (DefaultMutableTreeNode) path.getLastPathComponent();
 	        	Object userObject =	node.getUserObject();
 	        	//Only allow Hollon to move
-	        	if(userObject instanceof HolonInfo) {
-	        		return ((HolonInfo) userObject).getTransferable(this);
-	        		
+	        	if(this.allowHolonElementDragAndDrop) {
+	        		//Both
+	        		if(userObject instanceof HolonNode) {
+		        		return ((HolonNode) userObject).getTransferable(this);
+		        	}
+	        	}
+	        	else {
+	        		//Only Holons
+	        		if(userObject instanceof HolonInfo) {
+	        			return ((HolonInfo) userObject).getTransferable(this);
+	        		}
 	        	}
 	        }
 	        return null;
@@ -315,9 +441,9 @@ public class HolonView extends JPanel{
 		}
 	} 
 	
-	
+	//Cell Display
 	class HolonJtreeRenderer extends DefaultTreeCellRenderer {
-
+		
 	    public Component getTreeCellRendererComponent(
 	                        JTree tree,
 	                        Object value,
@@ -326,7 +452,7 @@ public class HolonView extends JPanel{
 	                        boolean leaf,
 	                        int row,
 	                        boolean hasFocus) {
-	         super.getTreeCellRendererComponent(tree, value, isSelected, expanded, leaf, row, hasFocus);
+	    	 super.getTreeCellRendererComponent(tree, value, isSelected, expanded, leaf, row, hasFocus);
 	         DefaultMutableTreeNode node = (DefaultMutableTreeNode) value;
 	         HolonNode Node = (HolonNode) node.getUserObject();
 	         if(row != 0) {
@@ -337,4 +463,38 @@ public class HolonView extends JPanel{
 	    }
 	}
 	
+	//Edit Names of Nodes
+	class HolonNodeEditor extends AbstractCellEditor implements TreeCellEditor{
+		private HolonNode holonNode; 
+		private JTextField tf= new JTextField(){
+		    @Override
+		    public Dimension getPreferredSize() {
+		        Dimension dim = super.getPreferredSize();
+		        int length = getText().length();
+		        dim.width = Math.max(300, dim.width + length * 10) ;
+		        return dim;
+		    }
+
+		};
+		public HolonNodeEditor() {
+			super();
+		}
+		@Override
+		public Object getCellEditorValue() {
+			holonNode.SetName(tf.getText());
+			return tf.getText();
+		}
+		
+
+		@Override
+		public Component getTreeCellEditorComponent(JTree tree, Object value, boolean isSelected, boolean expanded,
+				boolean leaf, int row) {
+			JLabel newString = (JLabel) holonTree.getCellRenderer().getTreeCellRendererComponent(tree, value, isSelected, expanded, leaf, row, leaf);
+			DefaultMutableTreeNode default_node = (DefaultMutableTreeNode) value; 
+			holonNode = (HolonNode)default_node.getUserObject();
+			tf.setText(newString.getText());
+			return tf;
+		}
+		
+	}
 }

+ 0 - 1
src/ui/view/outliner/Outliner.java

@@ -10,7 +10,6 @@ import javax.swing.event.TreeModelEvent;
 import javax.swing.event.TreeModelListener;
 import javax.swing.tree.DefaultMutableTreeNode;
 
-import classes.AbstractCanvasObject;
 import ui.controller.Control;
 import ui.model.Consumer;
 import ui.model.DecoratedCable;