Browse Source

Flexibility start not rdy

Tom 5 years ago
parent
commit
33affe7003

+ 16 - 2
src/classes/Flexibility.java

@@ -8,6 +8,8 @@ import java.util.function.Predicate;
  *
  */
 public class Flexibility {
+	/** The Name of a Flexibility.*/
+	public String name;
 	/** How fast in TimeSteps the Flexibility can be activated. */
 	public int speed;
 	/** How high the cost for a activation are. */
@@ -69,11 +71,23 @@ public class Flexibility {
 	}
 	
 	
+	
+	
+	
+	@Override
+	public String toString() {
+		return "Flexibility: " + name + " from [HolonElement: " + element.getEleName() + " ID:" + element.getId()+"]";
+	}
+
+
+
+
+
 	//Example Constrains:
 	/** Flexibility should be offered when Element is active.*/
-	public Predicate<Flexibility> onConstrain = f 	-> 	f.getElement().isActive();
+	public static Predicate<Flexibility> onConstrain = f 	-> 	f.getElement().isActive();
 	/** Flexibility should be offered when Element is inactive.*/
-	public Predicate<Flexibility> offConstrain = f	-> 	!f.getElement().isActive();
+	public static Predicate<Flexibility> offConstrain = f	-> 	!f.getElement().isActive();
 	
 	
 	

+ 2 - 1
src/classes/HolonElement.java

@@ -10,6 +10,7 @@ import ui.view.IndexTranslator;
 import java.awt.*;
 import java.awt.geom.Point2D;
 import java.awt.geom.Point2D.Double;
+import java.util.ArrayList;
 import java.util.LinkedList;
 import java.util.ListIterator;
 
@@ -54,7 +55,7 @@ public class HolonElement implements LocalMode, GraphEditable{
     private int id;
     
     
-    public java.util.List<Flexibility> flexList;
+    public java.util.List<Flexibility> flexList = new ArrayList<Flexibility>();
     
     /*
      * Energy at each point of the graph with 100 predefined points. At the

+ 407 - 0
src/exampleAlgorithms/FlexExample.java

@@ -0,0 +1,407 @@
+package exampleAlgorithms;
+
+import java.awt.BorderLayout;
+import java.awt.Component;
+import java.awt.Dimension;
+import java.awt.FlowLayout;
+import java.awt.image.BufferedImage;
+import java.text.NumberFormat;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.concurrent.TimeUnit;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+import javax.swing.BorderFactory;
+import javax.swing.ImageIcon;
+import javax.swing.JButton;
+import javax.swing.JCheckBox;
+import javax.swing.JFormattedTextField;
+import javax.swing.JFrame;
+import javax.swing.JLabel;
+import javax.swing.JOptionPane;
+import javax.swing.JPanel;
+import javax.swing.JProgressBar;
+import javax.swing.JScrollPane;
+import javax.swing.JSplitPane;
+import javax.swing.JTextArea;
+import javax.swing.text.NumberFormatter;
+
+import api.Algorithm;
+import classes.AbstractCpsObject;
+import classes.CpsUpperNode;
+import classes.HolonElement;
+import classes.HolonObject;
+import classes.HolonSwitch;
+import ui.controller.Control;
+import ui.model.DecoratedGroupNode;
+import ui.model.Model;
+
+public class FlexExample implements Algorithm {
+
+	//Parameter for Algo with default Values:
+		private boolean closeSwitches = true;
+		
+		//Settings For GroupNode using and cancel
+		private boolean useGroupNode = false;
+		private DecoratedGroupNode dGroupNode = null;
+		private boolean cancel = false;
+
+
+		//Parameter defined by Algo
+		private HashMap<Integer, AccessWrapper> access;
+		private List<Boolean> initialState;
+		private List<HolonSwitch> switchList;
+		private List<HolonObject> objectList;
+		
+		//Gui Part:
+		private Control  control;
+		private JTextArea textArea;
+		private JPanel content = new JPanel();
+		//ProgressBar
+		private JProgressBar progressBar = new JProgressBar();
+		private int progressBarCount = 0;
+		private long startTime;
+		private Thread runThread;
+
+		
+		
+		public static void main(String[] args)
+		{
+		      JFrame newFrame = new JFrame("exampleWindow");
+		      DemoAlgo instance = new DemoAlgo();
+		      newFrame.setContentPane(instance.getAlgorithmPanel());
+		      newFrame.pack();
+		      newFrame.setVisible(true);
+		      newFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+		}
+		public FlexExample() {
+			content.setLayout(new BorderLayout());
+		
+			textArea = new JTextArea();
+			textArea.setEditable(false);
+			JScrollPane scrollPane = new JScrollPane(textArea);
+			JSplitPane splitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT,
+					createOptionPanel() , scrollPane);
+			splitPane.setResizeWeight(0.0);
+			content.add(splitPane, BorderLayout.CENTER);
+			content.setPreferredSize(new Dimension(800,800));	
+		}
+		public JPanel createOptionPanel() {
+			JPanel optionPanel = new JPanel(new BorderLayout());
+			JScrollPane scrollPane = new JScrollPane(createParameterPanel());
+			scrollPane.setBorder(BorderFactory.createTitledBorder("Parameter"));
+			optionPanel.add(scrollPane,  BorderLayout.CENTER);
+			optionPanel.add(createButtonPanel(), BorderLayout.PAGE_END);
+			return optionPanel;
+		}
+		
+		private Component createParameterPanel() {
+			JPanel parameterPanel = new JPanel(null);
+			parameterPanel.setPreferredSize(new Dimension(510,300));
+			
+			
+		
+//			JLabel showDiagnosticsLabel = new JLabel("Set all switches closed:");
+//			showDiagnosticsLabel.setBounds(200, 60, 170, 20);
+//			parameterPanel.add(showDiagnosticsLabel);		
+		
+			
+			JPanel borderPanel = new JPanel(null);
+			borderPanel.setBounds(200, 85, 185, 50);
+			borderPanel.setBorder(BorderFactory.createTitledBorder(""));
+			parameterPanel.add(borderPanel);	
+			
+			JLabel showGroupNodeLabel = new JLabel("Use Group Node:");
+			showGroupNodeLabel.setBounds(10, 1, 170, 20);
+			borderPanel.add(showGroupNodeLabel);	
+			
+			JButton selectGroupNodeButton = new JButton("Select GroupNode");
+			selectGroupNodeButton.setEnabled(false);
+			selectGroupNodeButton.setBounds(10, 25, 165, 20);
+			selectGroupNodeButton.addActionListener(actionEvent -> selectGroupNode());
+			borderPanel.add(selectGroupNodeButton);	
+			
+			JCheckBox useGroupNodeCheckBox = new JCheckBox();
+			useGroupNodeCheckBox.setSelected(false);
+			useGroupNodeCheckBox.setBounds(155, 1, 25, 20);
+			useGroupNodeCheckBox.addActionListener(actionEvent -> {
+				useGroupNode = useGroupNodeCheckBox.isSelected();
+				selectGroupNodeButton.setEnabled(useGroupNode);
+			});
+			borderPanel.add(useGroupNodeCheckBox);
+			
+			
+			NumberFormat format = NumberFormat.getIntegerInstance();
+			format.setGroupingUsed(false);
+			format.setParseIntegerOnly(true);
+			NumberFormatter integerFormatter = new NumberFormatter(format);
+			integerFormatter.setMinimum(0);
+			integerFormatter.setCommitsOnValidEdit(true);
+			JLabel portLabel = new JLabel("between:");
+			portLabel.setBounds(10, 330, 70, 30);
+			parameterPanel.add(portLabel);
+			JLabel afterLabel = new JLabel("after:");
+			afterLabel.setBounds(10, 360, 70, 30);
+			parameterPanel.add(afterLabel);
+			
+			
+			return parameterPanel;
+		}
+		public JPanel createButtonPanel() {
+			JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT));
+			JButton cancelButton =  new JButton("Cancel Run");
+			cancelButton.addActionListener(actionEvent -> cancel());
+			buttonPanel.add(cancelButton);
+			JButton clearButton =  new JButton("Clear Console");
+			clearButton.addActionListener(actionEvent -> clear());
+			buttonPanel.add(clearButton);
+			JButton resetButton =  new JButton("Reset");
+			resetButton.setToolTipText("Resets the State to before the Algorithm has runed.");
+			resetButton.addActionListener(actionEvent -> reset());
+			buttonPanel.add(resetButton);
+			JButton runButton =  new JButton("Run");
+			runButton.addActionListener(actionEvent -> {
+				Runnable task = () -> run();
+				runThread = new Thread(task);
+				runThread.start();
+			});
+			buttonPanel.add(runButton);
+			return buttonPanel;
+		}
+		private void cancel() {
+			if(runThread.isAlive()) {
+				println("");
+				println("Cancel run.");
+				cancel = true;
+				progressBar.setValue(0);
+			} else {
+				println("Nothing to cancel.");
+			}
+		}
+		
+		private void run() {
+			cancel = false;
+			disableGuiInput(true);
+			startTimer();
+			executeDemoAlgo();
+			if(cancel) {
+				reset();
+				disableGuiInput(false);
+				return;
+			}
+			printElapsedTime();
+			disableGuiInput(false);
+		}
+		
+		private void reset() {
+			if(initialState != null) {
+				println("Resetting..");
+				resetState();
+				updateVisual();
+			}else {
+				println("No run inistialized.");
+			}
+		}
+		
+		
+		private void disableGuiInput(boolean bool) {
+			control.guiDiable(bool);
+		}
+		
+		
+		
+
+		
+		
+		@Override
+		public JPanel getAlgorithmPanel() {
+			return content;
+		}
+		@Override
+		public void setController(Control control) {
+			this.control = control;
+			
+		}
+		private void clear() {
+			textArea.setText("");
+		}
+		private void print(String message) {
+			textArea.append(message);
+		}
+		private void println(String message) {
+			textArea.append(message  + "\n");
+		}
+		private void selectGroupNode() {
+			Object[] possibilities = control.getSimManager().getActualVisualRepresentationalState().getCreatedGroupNodes().values().stream().map(aCps -> new Handle<DecoratedGroupNode>(aCps)).toArray();
+			@SuppressWarnings("unchecked")
+			Handle<DecoratedGroupNode> selected = (Handle<DecoratedGroupNode>) JOptionPane.showInputDialog(content, "Select GroupNode:", "GroupNode?",  JOptionPane.OK_OPTION,new ImageIcon(new BufferedImage(1, 1, BufferedImage.TYPE_INT_ARGB)) , possibilities, "");
+			if(selected != null) {
+				println("Selected: " + selected);
+				dGroupNode = selected.object;
+			}
+		}
+		private void progressBarStep(){
+			progressBar.setValue(++progressBarCount);
+		}
+		private void calculateProgressBarParameter() {
+			int max = 100;
+			progressBarCount = 0;
+			progressBar.setValue(0);
+			progressBar.setMaximum(max);
+		}
+		
+		private void startTimer(){
+			startTime = System.currentTimeMillis();
+		}
+		private void printElapsedTime(){
+			long elapsedMilliSeconds = System.currentTimeMillis() - startTime;
+			println("Execution Time of Algo in Milliseconds:" + elapsedMilliSeconds);
+		}
+		
+		
+		
+		
+		//Algo Part:
+		
+		private void executeDemoAlgo() {
+			extractPositionAndAccess();
+			int actualIteration = control.getModel().getCurIteration();
+			print("AlgoStart....");
+			
+			print("AlgoEnde....");
+			updateVisual();
+		}
+
+		
+		
+		/**
+		 * Method to get the current Position alias a ListOf Booleans for aktive settings on the Objects on the Canvas.
+		 * Also initialize the Access Hashmap to swap faster positions.
+		 * @param model
+		 * @return
+		 */
+		private List<Boolean> extractPositionAndAccess() {
+			Model model = control.getModel();
+			switchList = new ArrayList<HolonSwitch>();
+			objectList = new ArrayList<HolonObject>();
+			initialState = new ArrayList<Boolean>(); 
+			access= new HashMap<Integer, AccessWrapper>();
+			rollOutNodes((useGroupNode && (dGroupNode != null))? dGroupNode.getModel().getNodes() :model.getObjectsOnCanvas(), initialState, model.getCurIteration());
+			return initialState;
+		}
+		/**
+		 * Method to extract the Informations recursively out of the Model.
+		 * @param nodes
+		 * @param positionToInit
+		 * @param timeStep
+		 */
+		private void rollOutNodes(List<AbstractCpsObject> nodes, List<Boolean> positionToInit, int timeStep) {
+			for(AbstractCpsObject aCps : nodes) {
+				if (aCps instanceof HolonObject) {
+					for (HolonElement hE : ((HolonObject) aCps).getElements()) {
+						positionToInit.add(hE.isActive());
+						access.put(positionToInit.size() - 1 , new AccessWrapper(hE));
+					}
+					objectList.add((HolonObject) aCps);
+				}
+				else if (aCps instanceof HolonSwitch) {
+					HolonSwitch sw = (HolonSwitch) aCps;
+					positionToInit.add(sw.getState(timeStep));
+					switchList.add(sw);
+					access.put(positionToInit.size() - 1 , new AccessWrapper(sw));
+				}
+				else if(aCps instanceof CpsUpperNode) {
+					rollOutNodes(((CpsUpperNode)aCps).getNodes(), positionToInit ,timeStep );
+				}
+			}
+		}
+		/**
+		 * To let the User See the current state without touching the Canvas.
+		 */
+		private void updateVisual() {
+			control.calculateStateAndVisualForCurrentTimeStep();
+			control.updateCanvas();
+			control.getGui().triggerUpdateController(null);
+		}
+		/**
+		 * Sets the Model back to its original State before the LAST run.
+		 */
+		private void resetState() {
+			setState(initialState);
+		}
+		
+		/**
+		 * Sets the State out of the given position for calculation or to show the user.
+		 * @param position
+		 */
+		private void setState(List<Boolean> position) {
+			for(int i = 0;i<position.size();i++) {
+				access.get(i).setState(position.get(i));
+			}
+		}
+	
+
+
+
+		private void addObjectToList(List<AbstractCpsObject> listToSearch, List<HolonObject> listToAdd){
+			for (AbstractCpsObject aCps : listToSearch) {
+				if (aCps instanceof HolonObject) listToAdd.add((HolonObject) aCps);
+				else if(aCps instanceof CpsUpperNode) {
+					addObjectToList(((CpsUpperNode)aCps).getNodes(),listToAdd);
+				}
+			}
+		}
+		
+		
+		
+		
+		/**
+		 * A Wrapper Class for Access HolonElement and HolonSwitch in one Element and not have to split the List.
+		 */
+		private class AccessWrapper {
+			public static final int HOLONELEMENT = 0;
+			public static final int SWITCH = 1;
+			private int type;
+			private HolonSwitch hSwitch;
+			private HolonElement hElement;
+			public AccessWrapper(HolonSwitch hSwitch){
+				type = SWITCH;
+				this.hSwitch = hSwitch;
+			}
+			public AccessWrapper(HolonElement hElement){
+				type = HOLONELEMENT;
+				this.hElement = hElement;
+			}
+			public void setState(boolean state) {
+				if(type == HOLONELEMENT) {
+					hElement.setActive(state);
+				}else{//is switch
+					hSwitch.setManualMode(true);
+					hSwitch.setManualState(state);
+				}
+					
+			}
+			public boolean getState(int timeStep) {
+				return (type == HOLONELEMENT)?hElement.isActive():hSwitch.getState(timeStep);
+			}
+			public int getType() {
+				return type;
+			}
+		}
+		
+		
+		
+		
+		private   class  Handle<T>{
+			public T object;
+			Handle(T object){
+				this.object = object;
+			}
+			public String toString() {
+				return object.toString();
+			}
+		}
+
+}

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

@@ -133,6 +133,8 @@ public class ObjectController {
      */
     public void addSelectedObject(AbstractCpsObject obj) {
         model.getSelectedCpsObjects().add(obj);
+        
+        System.out.println("Add Object");
     }
 
     /**

+ 487 - 0
src/ui/view/FlexWindow.java

@@ -0,0 +1,487 @@
+package ui.view;
+
+import java.awt.BorderLayout;
+import java.awt.Color;
+import java.awt.Component;
+import java.awt.FlowLayout;
+import java.awt.Dialog.ModalityType;
+import java.awt.event.ItemEvent;
+import java.awt.image.BufferedImage;
+import java.math.RoundingMode;
+import java.text.NumberFormat;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Locale;
+
+import javax.swing.BorderFactory;
+import javax.swing.Box;
+import javax.swing.BoxLayout;
+import javax.swing.DefaultComboBoxModel;
+import javax.swing.ImageIcon;
+import javax.swing.JButton;
+import javax.swing.JCheckBox;
+import javax.swing.JComboBox;
+import javax.swing.JDialog;
+import javax.swing.JFormattedTextField;
+import javax.swing.JFrame;
+import javax.swing.JLabel;
+import javax.swing.JMenu;
+import javax.swing.JMenuBar;
+import javax.swing.JMenuItem;
+import javax.swing.JOptionPane;
+import javax.swing.JPanel;
+import javax.swing.JScrollPane;
+import javax.swing.JTabbedPane;
+import javax.swing.JTree;
+import javax.swing.border.EmptyBorder;
+import javax.swing.text.NumberFormatter;
+import javax.swing.tree.DefaultMutableTreeNode;
+import javax.swing.tree.DefaultTreeModel;
+
+import classes.AbstractCpsObject;
+import classes.CpsUpperNode;
+import classes.Flexibility;
+import classes.HolonElement;
+import classes.HolonObject;
+import ui.model.Model;
+
+
+public class FlexWindow extends JFrame {
+	private JPanel nothingSelectedPanel;
+	private JPanel selectedPanel;
+	
+	
+	private JTabbedPane contentPanel = new JTabbedPane();
+	private JPanel usageViewPanel;
+	
+	private Model model;
+	
+	
+	
+	//Flexibility Intermediate
+	private Flexibility intermediateFlex = new Flexibility(null);
+	private boolean offered = true, onConstrain = true, offConstrain =false;
+	
+	
+	
+	//JTree
+	private DefaultMutableTreeNode listOfAllSelectedHolonObjects;
+	private JTree stateTree;
+	private DefaultTreeModel treeModel;
+	
+	
+	
+	
+	public FlexWindow(JFrame parentFrame, Model model){
+		this.intermediateFlex.name = "name";
+		//InitWindow
+		createMenuBar();
+		initWindowPanel(parentFrame);
+		this.model = model;
+		selectedCpsObjectsChanged();
+		System.out.println("Ich wurde erstellt.");
+		//this.pack();
+	}
+
+
+
+	private void initWindowPanel(JFrame parentFrame) {
+		this.setBounds(0, 0, 400, parentFrame.getHeight()>20?parentFrame.getHeight()- 20:parentFrame.getHeight());
+		this.setIconImage(Util.loadImage("/Images/Holeg.png", 30, 30));
+		this.setTitle("Flexibility");
+		this.setLocationRelativeTo(parentFrame);
+		this.setVisible(true);
+		
+		createNothingSelectedPanel();
+		createSelectedPanel();
+		createUsageViewPanel();
+		contentPanel.addTab("Settings", nothingSelectedPanel);
+		contentPanel.addTab("Order", usageViewPanel);
+		contentPanel.setBorder(new EmptyBorder(5, 5, 5, 5));
+		this.setContentPane(contentPanel);
+		this.revalidate();
+		
+	}
+
+	private void createMenuBar(){
+		JMenuBar menuBar = new JMenuBar();
+		JMenu canvas = new JMenu("Canvas");
+		menuBar.add(canvas);
+		JMenuItem selectAllMenuItem = new JMenuItem("Select All");
+		selectAllMenuItem.addActionListener(clicked -> selectAll());
+		canvas.add(selectAllMenuItem);
+		JMenuItem updateMenuItem = new JMenuItem("Update");
+		updateMenuItem.addActionListener(clicked -> selectedCpsObjectsChanged());
+		canvas.add(updateMenuItem);
+		JMenu flex = new JMenu("Flex");
+		menuBar.add(flex);
+		JMenuItem addMenuItem = new JMenuItem("Add Flexibility");
+		addMenuItem.addActionListener(clicked -> createAddDialog());
+		flex.add(addMenuItem);
+		JMenuItem deleteMenuItem = new JMenuItem("Delete Flexibility");
+		deleteMenuItem.addActionListener(clicked -> createDeleteDialog());
+		flex.add(deleteMenuItem);
+		
+		this.setJMenuBar(menuBar);
+	}
+	
+	
+	private void selectAll() {
+		model.getSelectedCpsObjects().clear();
+		model.getSelectedCpsObjects().addAll(model.getObjectsOnCanvas());
+		selectedCpsObjectsChanged();
+	}
+
+	
+	private void createUsageViewPanel() {
+		usageViewPanel = new JPanel();
+		usageViewPanel.setLayout(new BoxLayout(usageViewPanel, BoxLayout.PAGE_AXIS));
+		usageViewPanel.add(new JLabel("Test bla"));
+		addFlexToUsageView(this.intermediateFlex);
+		addFlexToUsageView(this.intermediateFlex);
+		addFlexToUsageView(this.intermediateFlex);
+		addFlexToUsageView(this.intermediateFlex);
+		addFlexToUsageView(this.intermediateFlex);
+	}
+	
+	private void addFlexToUsageView(Flexibility flex) {
+		JPanel newFlexRow = new JPanel(new FlowLayout( FlowLayout.CENTER));
+		newFlexRow.add(new JLabel(flex.name));
+		JButton useFlexButton = new JButton("Use Flex");
+		useFlexButton.addActionListener(clicked ->{
+			System.out.println("Use Flex button pressed");
+		});
+		newFlexRow.add(useFlexButton);
+		
+		usageViewPanel.add(newFlexRow);
+	}
+	
+
+
+	private void createSelectedPanel() {
+		//Liste aller Flexibilities
+		listOfAllSelectedHolonObjects = new DefaultMutableTreeNode("HolonObjects");
+		treeModel = new DefaultTreeModel(listOfAllSelectedHolonObjects);
+		stateTree = new JTree(treeModel);
+		selectedPanel = new JPanel(new BorderLayout());
+		selectedPanel.add(new JScrollPane(stateTree));
+	}
+
+
+	private void createNothingSelectedPanel() {
+		nothingSelectedPanel = new JPanel();
+		nothingSelectedPanel.setLayout(new BoxLayout(nothingSelectedPanel, BoxLayout.PAGE_AXIS));
+		JLabel nothingSelectedTextLabel = new JLabel("No HolonObject selected.");
+		nothingSelectedTextLabel.setForeground(Color.gray);
+		nothingSelectedTextLabel.setAlignmentX(Component.CENTER_ALIGNMENT);
+		nothingSelectedPanel.add(Box.createVerticalGlue());
+		nothingSelectedPanel.add(nothingSelectedTextLabel);
+		nothingSelectedPanel.add(Box.createVerticalGlue());
+	}
+	
+	public void selectedCpsObjectsChanged() {
+		if(model.getSelectedCpsObjects().isEmpty()) {
+			contentPanel.setComponentAt(contentPanel.indexOfTab("Settings"), nothingSelectedPanel);
+			contentPanel.revalidate();
+			//this.revalidate();
+			return;
+		}
+		
+		listOfAllSelectedHolonObjects.removeAllChildren();
+		//Init with HolonObjects
+		for(AbstractCpsObject aCps: model.getSelectedCpsObjects()) {
+			DefaultMutableTreeNode newObjectChild = new DefaultMutableTreeNode(aCps.getName());
+			if(aCps instanceof HolonObject) expandTreeHolonObject((HolonObject)aCps, newObjectChild);
+			if(aCps instanceof CpsUpperNode)expandTreeUpperNode((CpsUpperNode)aCps, newObjectChild);
+			listOfAllSelectedHolonObjects.add(newObjectChild);
+			System.out.println("Added: " + aCps.getName());
+		}
+		treeModel.nodeStructureChanged(listOfAllSelectedHolonObjects);
+		stateTree.revalidate();
+		expandAll(stateTree);
+		selectedPanel.revalidate();
+		contentPanel.setComponentAt(contentPanel.indexOfTab("Settings"), selectedPanel);
+		contentPanel.revalidate();
+		this.revalidate();
+	}
+
+
+
+	private void expandAll(JTree tree) {
+		for(int i = 0; i< tree.getRowCount() ; i++) {
+			tree.expandRow(i);
+		}
+		
+	}
+
+
+
+	private void expandTreeUpperNode(CpsUpperNode groupNode, DefaultMutableTreeNode root) {
+		for(AbstractCpsObject aCps: groupNode.getNodes()) {
+			DefaultMutableTreeNode newObjectChild = new DefaultMutableTreeNode(aCps.getName());
+			if(aCps instanceof HolonObject) expandTreeHolonObject((HolonObject)aCps, newObjectChild);
+			if(aCps instanceof CpsUpperNode)expandTreeUpperNode((CpsUpperNode)aCps, newObjectChild);
+			root.add(newObjectChild);
+		}
+		
+	}
+
+
+
+	private void expandTreeHolonObject(HolonObject hObject, DefaultMutableTreeNode root) {
+		for(HolonElement hElement: hObject.getElements()) {
+			DefaultMutableTreeNode newChild = new DefaultMutableTreeNode(hElement.getEleName());
+			expandTreeFlex(hElement, newChild);
+			root.add(newChild);
+		}
+	}
+	private void expandTreeFlex(HolonElement hElement, DefaultMutableTreeNode root) {
+		for(Flexibility flex: hElement.flexList) {
+			DefaultMutableTreeNode newChild = new DefaultMutableTreeNode("<html>"+"Flex: "+ "<b>" + flex.name+ "</b>" + "</html>");
+			root.add(newChild);
+		}
+	}
+	
+	
+	private void createDeleteDialog() {
+		
+		List<HolonObject> list= createListOfHolonObjects(model.getObjectsOnCanvas());
+		
+		//String test = list.stream().map(Object::toString).collect(Collectors.joining(","));
+		Object[] allFlexes = list.stream().flatMap(hObject -> hObject.getElements().stream()).flatMap(hElement -> hElement.flexList.stream()).toArray(size -> new Flexibility[size]);
+		if(allFlexes.length == 0) {
+			JOptionPane.showMessageDialog(this,
+					"No Flexibility exist.",
+					"Warning",
+					JOptionPane.WARNING_MESSAGE);
+			return;
+		}
+		
+		
+		
+		Flexibility toDeleteFlex =(Flexibility) JOptionPane.showInputDialog(this, "Select to Delete Flexibility:", "Flexibility?",  JOptionPane.OK_OPTION,new ImageIcon(new BufferedImage(1, 1, BufferedImage.TYPE_INT_ARGB)) , allFlexes, "");
+		if(toDeleteFlex != null) {
+			System.out.println("ToDelete:" + toDeleteFlex);
+			toDeleteFlex.getElement().flexList.remove(toDeleteFlex);
+			selectedCpsObjectsChanged();
+		}
+	}
+	
+	
+	
+	private List<HolonObject> createListOfHolonObjects(List<AbstractCpsObject> objectsOnCanvas) {
+		List<HolonObject> list = new ArrayList<HolonObject>();
+		for(AbstractCpsObject aCps :  objectsOnCanvas) {
+			if(aCps instanceof HolonObject) list.add((HolonObject) aCps);
+			else list.addAll(createListOfHolonObjects(((CpsUpperNode)aCps).getNodes()));
+		}
+		return list;
+	}
+
+
+
+	//Add Element
+	private void createAddDialog(){
+		if(model.getObjectsOnCanvas().isEmpty()) {
+			JOptionPane.showMessageDialog(this,
+					"No HolonObject exist.",
+					"Warning",
+					JOptionPane.WARNING_MESSAGE);
+			return;
+		}
+		JDialog addDialog = new JDialog();
+		addDialog.setTitle("Create Flexibility");
+		addDialog.setBounds(0, 0, 820, 400);	
+		addDialog.setDefaultCloseOperation(DISPOSE_ON_CLOSE);
+		JPanel dialogPanel = new JPanel(new BorderLayout());
+		addDialog.setContentPane(dialogPanel);
+		JPanel selectionPanel = new JPanel(null);
+		dialogPanel.add(selectionPanel, BorderLayout.CENTER);
+		JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT));
+		dialogPanel.add(buttonPanel, BorderLayout.PAGE_END);
+		
+		
+		
+		
+		addDialog.setModalityType(ModalityType.APPLICATION_MODAL);
+		//Erstelle HolonObject AuswahlBox
+		HolonObject[] holonObjects = createListOfHolonObjects(model.getObjectsOnCanvas()).stream().toArray(HolonObject[]::new);
+
+		DefaultComboBoxModel<HolonObject> comboBoxModel = new DefaultComboBoxModel<HolonObject>( holonObjects );
+
+
+		JComboBox<HolonObject> holonObjectSelector = new JComboBox<HolonObject>(comboBoxModel);
+		holonObjectSelector.setBounds(10,30, 800, 30);
+		selectionPanel.add(holonObjectSelector);
+		
+		DefaultComboBoxModel<HolonElement> comboBoxModelElements = new DefaultComboBoxModel<HolonElement>( holonObjects[0].getElements().stream().toArray(size -> new HolonElement[size]));
+		JComboBox<HolonElement> holonElementSelector = new JComboBox<HolonElement>(comboBoxModelElements);
+		holonElementSelector.setBounds(10,80, 800, 30);
+		selectionPanel.add(holonElementSelector);
+		
+		
+		holonObjectSelector.addItemListener(aListener -> {
+			if(aListener.getStateChange() == ItemEvent.SELECTED) {
+				System.out.println("Selected");
+				DefaultComboBoxModel<HolonElement> newComboBoxModelElements = new DefaultComboBoxModel<HolonElement>( ((HolonObject) aListener.getItem()).getElements().stream().toArray(size -> new HolonElement[size]));
+				holonElementSelector.setModel(newComboBoxModelElements);
+			}
+		});
+		
+		JLabel selectObjectLabel = new JLabel("Select HolonObject:");
+		selectObjectLabel.setBounds(10, 10, 200, 20);
+		selectionPanel.add(selectObjectLabel);
+		JLabel selectElementLabel = new JLabel("Select HolonElement:");
+		selectElementLabel.setBounds(10, 60, 200, 20);
+		selectionPanel.add(selectElementLabel);
+		
+		JPanel flexAttributesBorderPanel = new  JPanel(null);
+		flexAttributesBorderPanel.setBounds(10, 120, 800, 200);
+		flexAttributesBorderPanel.setBorder(BorderFactory.createTitledBorder("Flexibility Attributes"));
+		selectionPanel.add(flexAttributesBorderPanel);	
+		JLabel flexNameLabel = new JLabel("Name:");
+		flexNameLabel.setBounds(10,20, 50, 20);
+		flexAttributesBorderPanel.add(flexNameLabel);
+		JFormattedTextField nameTextField = new JFormattedTextField(intermediateFlex.name);
+		nameTextField.addPropertyChangeListener(changed -> intermediateFlex.name = nameTextField.getText());
+		nameTextField.setBounds(80, 15, 200, 30);
+		flexAttributesBorderPanel.add(nameTextField);
+		JLabel flexSpeedLabel = new JLabel("Speed:");
+		flexSpeedLabel.setBounds(10,55, 50, 20);
+		flexAttributesBorderPanel.add(flexSpeedLabel);
+		//Integer formatter
+		NumberFormat format = NumberFormat.getIntegerInstance();
+		format.setGroupingUsed(false);
+		format.setParseIntegerOnly(true);
+		NumberFormatter integerFormatter = new NumberFormatter(format);
+		integerFormatter.setMinimum(0);
+		integerFormatter.setCommitsOnValidEdit(true);
+		
+		
+		JFormattedTextField speedTextField = new  JFormattedTextField(integerFormatter);
+		speedTextField.setValue(intermediateFlex.speed);
+		speedTextField.setToolTipText("Only positive Integer.");
+		speedTextField.addPropertyChangeListener(actionEvent -> intermediateFlex.speed = Integer.parseInt(speedTextField.getValue().toString()));
+		speedTextField.setBounds(80, 50, 200, 30);
+		flexAttributesBorderPanel.add(speedTextField);
+		speedTextField.setEnabled(false);
+		
+		JLabel flexDurationLabel = new JLabel("Duration:");
+		flexDurationLabel.setBounds(10,90, 70, 20);
+		flexAttributesBorderPanel.add(flexDurationLabel);
+		
+		
+		NumberFormatter moreThenZeroIntegerFormater = new NumberFormatter(format);
+		moreThenZeroIntegerFormater.setMinimum(1);
+		moreThenZeroIntegerFormater.setCommitsOnValidEdit(true);
+		
+		JFormattedTextField durationTextField = new  JFormattedTextField(moreThenZeroIntegerFormater);
+		durationTextField.setValue(intermediateFlex.getDuration());
+		durationTextField.setToolTipText("Only positive Integer bigger then 0.");
+		durationTextField.addPropertyChangeListener(actionEvent -> intermediateFlex.setDuration(Integer.parseInt(durationTextField.getValue().toString())));
+		durationTextField.setBounds(80, 85, 200, 30);
+		flexAttributesBorderPanel.add(durationTextField);
+		
+		JLabel flexCostsLabel = new JLabel("Costs:");
+		flexCostsLabel.setBounds(10,125, 70, 20);
+		flexAttributesBorderPanel.add(flexCostsLabel);
+		
+		//Double Format:
+		NumberFormat doubleFormat = NumberFormat.getNumberInstance(Locale.US);
+		doubleFormat.setMinimumFractionDigits(1);
+		doubleFormat.setMaximumFractionDigits(2);
+		doubleFormat.setRoundingMode(RoundingMode.HALF_UP);
+
+		//CostFormatter:
+		NumberFormatter costsFormatter = new NumberFormatter(doubleFormat);
+		costsFormatter.setMinimum(0.0);
+		
+		JFormattedTextField costTextField = new JFormattedTextField(costsFormatter);
+		costTextField.setValue(intermediateFlex.cost);
+		costTextField.setToolTipText("Only non negative Double with DecimalSeperator Point('.').");
+		costTextField.addPropertyChangeListener(propertyChange -> intermediateFlex.cost = Float.parseFloat(costTextField.getValue().toString()));
+		costTextField.setBounds(80, 120, 200, 30);
+		flexAttributesBorderPanel.add(costTextField);
+		
+		
+		
+		JLabel flexCooldownLabel = new JLabel("Cooldown:");
+		flexCooldownLabel.setBounds(310,20, 70, 20);
+		flexAttributesBorderPanel.add(flexCooldownLabel);
+		
+		
+		JFormattedTextField cooldownTextField = new  JFormattedTextField(moreThenZeroIntegerFormater);
+		cooldownTextField.setValue(intermediateFlex.getCooldown());
+		cooldownTextField.setToolTipText("Only positive Integer.");
+		cooldownTextField.addPropertyChangeListener(actionEvent -> intermediateFlex.setCooldown(Integer.parseInt(cooldownTextField.getValue().toString())));
+		cooldownTextField.setBounds(380, 15, 200, 30);
+		flexAttributesBorderPanel.add(cooldownTextField);
+		
+		JCheckBox offeredCheckBox = new JCheckBox("Offered");
+		offeredCheckBox.setSelected(this.offered);
+		offeredCheckBox.setBounds(310, 55, 200, 20);
+		flexAttributesBorderPanel.add(offeredCheckBox);
+		
+		JCheckBox onConstrainCheckBox = new JCheckBox("On_Constrain");
+		onConstrainCheckBox.setSelected(this.onConstrain);
+		onConstrainCheckBox.setBounds(310, 80, 200, 20);
+		flexAttributesBorderPanel.add(onConstrainCheckBox);
+		
+		JCheckBox offConstrainCheckBox = new JCheckBox("Off_Constrain");
+		offConstrainCheckBox.setSelected(this.offConstrain);
+		offConstrainCheckBox.setBounds(310, 105, 200, 20);
+		flexAttributesBorderPanel.add(offConstrainCheckBox);
+		
+		
+		
+		
+		//Both cant be true....
+		onConstrainCheckBox.addActionListener(clicked -> {
+			if(onConstrainCheckBox.isSelected()) offConstrainCheckBox.setSelected(false);
+			});
+		offConstrainCheckBox.addActionListener(clicked -> {
+			if(offConstrainCheckBox.isSelected()) onConstrainCheckBox.setSelected(false);
+			});
+		
+		JButton createFlexButton = new JButton("Create");
+		createFlexButton.addActionListener(clicked -> {
+			//createFlexButton.requestFocus();
+			//createFlexButton.grabFocus();
+			HolonElement ele = (HolonElement) holonElementSelector.getSelectedItem();
+			Flexibility toCreateFlex = new Flexibility(ele);
+			toCreateFlex.name = intermediateFlex.name;
+			toCreateFlex.speed = intermediateFlex.speed;
+			toCreateFlex.setDuration(intermediateFlex.getDuration());
+			toCreateFlex.cost = intermediateFlex.cost;
+			toCreateFlex.setCooldown(intermediateFlex.getCooldown());
+			toCreateFlex.offered=offeredCheckBox.isSelected();
+			if(onConstrainCheckBox.isSelected())toCreateFlex.constrainList.add(Flexibility.onConstrain);
+			if(offConstrainCheckBox.isSelected())toCreateFlex.constrainList.add(Flexibility.offConstrain);
+			
+			ele.flexList.add(toCreateFlex);
+			//save checkboxes
+			this.offered=offeredCheckBox.isSelected();
+			this.onConstrain = onConstrainCheckBox.isSelected();
+			this.offConstrain = offConstrainCheckBox.isSelected();
+			
+			
+			if(!model.getSelectedCpsObjects().contains(holonObjectSelector.getSelectedItem()))model.getSelectedCpsObjects().add((AbstractCpsObject)holonObjectSelector.getSelectedItem());
+			selectedCpsObjectsChanged();
+			addDialog.dispose();
+		});
+		buttonPanel.add(createFlexButton);
+		JButton cancelButton = new JButton("Cancel");
+		cancelButton.addActionListener(clicked -> {
+			addDialog.dispose();
+		});
+		buttonPanel.add(cancelButton);
+		
+		
+		
+		//last 
+		addDialog.setLocationRelativeTo(this);
+		addDialog.setVisible(true);
+	}
+	
+	
+}

+ 65 - 58
src/ui/view/GUI.java

@@ -266,7 +266,7 @@ public class GUI implements CategoryListener {
 	private final JLabel lblSelectedElement = new JLabel("Selected Element: ");
 	// for doubleclick
 	private boolean click = false;
-	private JFrame frmCyberPhysical;
+	private JFrame holegJFrame;
 	private JTabbedPane tabTemp; // tabbedPaneOriginal or tabbedPaneSplit
 	private JSplitPane tempSplit;
 	private boolean initSplit = true;
@@ -336,13 +336,13 @@ public class GUI implements CategoryListener {
 	 */
 	@SuppressWarnings({ "serial", "unchecked" })
 	private void initialize() {
-		frmCyberPhysical = new JFrame();
-		frmCyberPhysical.setTitle("HOLEG Simulator");
+		holegJFrame = new JFrame();
+		holegJFrame.setTitle("HOLEG Simulator");
 		// try to restore old position/dimensions
 		ArrayList<Integer> savedWindowDim = controller
 				.loadSavedWindowDimensionsIfExistent();
 		if (savedWindowDim.size() == 4) {
-			frmCyberPhysical.setBounds(savedWindowDim.get(0),
+			holegJFrame.setBounds(savedWindowDim.get(0),
 					savedWindowDim.get(1), savedWindowDim.get(2),
 					savedWindowDim.get(3));
 		}
@@ -351,15 +351,15 @@ public class GUI implements CategoryListener {
 		// moved,
 		// but if it is not, we need to move it to somewhere else
 		if (savedWindowDim.size() != 4 || !isUpperPanelInsideBounds()) {
-			frmCyberPhysical.setBounds(100, 100, 1000, 800);
-			frmCyberPhysical.setExtendedState(JFrame.MAXIMIZED_BOTH);
+			holegJFrame.setBounds(100, 100, 1000, 800);
+			holegJFrame.setExtendedState(JFrame.MAXIMIZED_BOTH);
 		}
-		frmCyberPhysical.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
+		holegJFrame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
 
-		frmCyberPhysical.addWindowListener(new java.awt.event.WindowAdapter() {
+		holegJFrame.addWindowListener(new java.awt.event.WindowAdapter() {
 			@Override
 			public void windowClosing(java.awt.event.WindowEvent windowEvent) {
-				if (JOptionPane.showConfirmDialog(frmCyberPhysical,
+				if (JOptionPane.showConfirmDialog(holegJFrame,
 						Languages.getLanguage()[88],
 						"HOLEG",
 						JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE) == JOptionPane.YES_OPTION) {
@@ -372,10 +372,10 @@ public class GUI implements CategoryListener {
 					// it can be opened in the same position the next time
 					try {
 						controller.savePosAndSizeOfWindow(
-								frmCyberPhysical.getX(),
-								frmCyberPhysical.getY(),
-								frmCyberPhysical.getWidth(),
-								frmCyberPhysical.getHeight());
+								holegJFrame.getX(),
+								holegJFrame.getY(),
+								holegJFrame.getWidth(),
+								holegJFrame.getHeight());
 					} catch (Exception e) {
 						e.printStackTrace();
 					}
@@ -384,7 +384,7 @@ public class GUI implements CategoryListener {
 			}
 		});
 
-		contentPane = (JPanel) frmCyberPhysical.getContentPane();
+		contentPane = (JPanel) holegJFrame.getContentPane();
 
 		int condition = JComponent.WHEN_IN_FOCUSED_WINDOW;
 		InputMap inputMap = contentPane.getInputMap(condition);
@@ -572,7 +572,7 @@ public class GUI implements CategoryListener {
 			@Override
 			public void actionPerformed(ActionEvent e) {
 				SearchPopUp dialog = new SearchPopUp(controller, canvas,
-						frmCyberPhysical);
+						holegJFrame);
 				dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
 				dialog.setVisible(true);
 			}
@@ -644,7 +644,7 @@ public class GUI implements CategoryListener {
 						| UnsupportedFlavorException | IOException e1) {
 					JLabel message = new JLabel(
 							"The Clipboard information cannot be pasted into Application.");
-					JOptionPane.showMessageDialog(frmCyberPhysical, message,
+					JOptionPane.showMessageDialog(holegJFrame, message,
 							"", JOptionPane.ERROR_MESSAGE);
 				}
 
@@ -681,9 +681,9 @@ public class GUI implements CategoryListener {
 		};
 		actionMap.put(cntrlXDown, controlX);
 
-		frmCyberPhysical.setJMenuBar(menuBar);
+		holegJFrame.setJMenuBar(menuBar);
 
-		frmCyberPhysical.setIconImage(Util.loadImage(
+		holegJFrame.setIconImage(Util.loadImage(
 				"/Images/Holeg.png", 30, 30));
 
 		menuBar.add(mnNewMenu);
@@ -724,7 +724,7 @@ public class GUI implements CategoryListener {
 		mntmFindReplace.addActionListener(actionEvent -> {
 			try {
 				SearchPopUp dialog = new SearchPopUp(controller, canvas,
-						frmCyberPhysical);
+						holegJFrame);
 				dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
 				dialog.setVisible(true);
 				controller.getObjectsInDepth();
@@ -739,7 +739,7 @@ public class GUI implements CategoryListener {
 					try {
 						DisplayedInformationPopUp dialog = new DisplayedInformationPopUp(
 								canvas, contentPane, controller,
-								frmCyberPhysical);
+								holegJFrame);
 						dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
 						dialog.setVisible(true);
 					} catch (Exception ex) {
@@ -751,7 +751,7 @@ public class GUI implements CategoryListener {
 		mnNewMenuEdit.add(mntmEditShowedInformation);
 		mnNewMenuEdit.add(mntmEditEdges);
 		mntmEditEdges.addActionListener(actionEvent -> {
-			EditEdgesPopUp edgePopUp = new EditEdgesPopUp(frmCyberPhysical);
+			EditEdgesPopUp edgePopUp = new EditEdgesPopUp(holegJFrame);
 			edgePopUp.setCanvas(canvas);
 			edgePopUp.setController(controller);
 			edgePopUp.setVisible(true);
@@ -848,7 +848,7 @@ public class GUI implements CategoryListener {
 		mntmCanvasSize.addActionListener(actionEvent -> {
 			CanvasResizePopUp popUp = new CanvasResizePopUp(model, controller,
 					canvas, tabbedPaneOriginal, tabbedPaneSplit,
-					frmCyberPhysical);
+					holegJFrame);
 			popUp.setVisible(true);
 		});
 		
@@ -949,7 +949,7 @@ public class GUI implements CategoryListener {
 					if (scrollPane.getViewport().getComponent(0) instanceof MyCanvas) {
 						BackgroundPopUp backgroundDialog = new BackgroundPopUp(
 								model, controller, canvas, null,
-								frmCyberPhysical);
+								holegJFrame);
 						backgroundDialog
 								.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
 						backgroundDialog.setVisible(true);
@@ -958,7 +958,7 @@ public class GUI implements CategoryListener {
 								.getViewport().getComponent(0));
 						BackgroundPopUp backgroundDialog = new BackgroundPopUp(
 								model, controller, null, uNodeCanvas.upperNode,
-								frmCyberPhysical);
+								holegJFrame);
 						backgroundDialog
 								.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
 						backgroundDialog.setVisible(true);
@@ -1193,7 +1193,7 @@ public class GUI implements CategoryListener {
 				if (tempCpsObject != null
 						&& tempCpsObject.getClass() == HolonObject.class
 						&& tempCpsObject.getId() != 0) {
-					addElementPopUp = new AddElementPopUp(frmCyberPhysical, model);//TODO: I didn't even check
+					addElementPopUp = new AddElementPopUp(holegJFrame, model);//TODO: I didn't even check
 					addElementPopUp.setActualCps(updCon.getActualCps());
 					addElementPopUp.setVisible(true);
 					HolonElement ele = addElementPopUp.getElement();
@@ -1682,7 +1682,7 @@ public class GUI implements CategoryListener {
 		 * RIGHT CONTAINER DONE
 		 *****************************/
 
-		frmCyberPhysical.getContentPane().setLayout(new BorderLayout(0, 0));
+		holegJFrame.getContentPane().setLayout(new BorderLayout(0, 0));
 		/****************
 		 * Tree Stuff
 		 ****************/
@@ -1902,7 +1902,7 @@ public class GUI implements CategoryListener {
 					}
 				} catch (Exception eex) {
 				}
-				frmCyberPhysical.setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
+				holegJFrame.setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
 			}
 		});
 		
@@ -1973,7 +1973,7 @@ public class GUI implements CategoryListener {
 									Cursor cursor = Toolkit.getDefaultToolkit()
 											.createCustomCursor(img,
 													new Point(0, 0), "Image");
-									frmCyberPhysical.setCursor(cursor);
+									holegJFrame.setCursor(cursor);
 								}
 							}
 						}
@@ -1986,7 +1986,7 @@ public class GUI implements CategoryListener {
 			// Remove the selected Object object
 			//AddObjectPopUp(boolean edit, AbstractCpsObject obj, String cat, JFrame parentFrame)
 			addObjectPopUP = new AddObjectPopUp(true, tempCps,
-					catOfObjToBeEdited, frmCyberPhysical);
+					catOfObjToBeEdited, holegJFrame);
 			addObjectPopUP.setCategory(catOfObjToBeEdited);
 			addObjectPopUP.setController(controller);
 			addObjectPopUP.setVisible(true);
@@ -2001,24 +2001,24 @@ public class GUI implements CategoryListener {
 		panel.add(toolBar);
 		btnAddPopUp.add(mItemNew);
 		mItemNew.addActionListener(actionEvent -> {
-			new NewPopUp(controller, frmCyberPhysical);
+			new NewPopUp(controller, holegJFrame);
 		});
 		btnAddPopUp.addSeparator();
 		btnAddPopUp.add(mItemCategory);
 		mItemCategory.addActionListener(actionEvent -> {
-			new NewPopUp(controller,Option.Category, frmCyberPhysical);
+			new NewPopUp(controller,Option.Category, holegJFrame);
 		});
 		btnAddPopUp.add(mItemObject);
 		mItemObject.addActionListener(actionEvent -> {
-			new NewPopUp(controller,Option.Object, frmCyberPhysical);
+			new NewPopUp(controller,Option.Object, holegJFrame);
 		});
 		btnAddPopUp.add(mItemSwitch);
 		mItemSwitch.addActionListener(actionEvent -> {
-			new NewPopUp(controller,Option.Switch, frmCyberPhysical);
+			new NewPopUp(controller,Option.Switch, holegJFrame);
 		});
 		btnAddPopUp.add(mItemBattery);
 		mItemBattery.addActionListener(actionEvent -> {
-			new NewPopUp(controller,Option.Battery, frmCyberPhysical);
+			new NewPopUp(controller,Option.Battery, holegJFrame);
 		});
 		btnAdd.addActionListener(actionEvent -> btnAddPopUp.show(btnAdd, -1, +20));
 		btnAdd.setToolTipText("Add a new Category or Item to the library.");
@@ -2071,7 +2071,7 @@ public class GUI implements CategoryListener {
 		mntmAboutUs.addMouseListener(new MouseAdapter() {
 			@Override
 			public void mousePressed(MouseEvent e) {
-				aboutUsPopUp = new AboutUsPopUp(frmCyberPhysical);
+				aboutUsPopUp = new AboutUsPopUp(holegJFrame);
 				aboutUsPopUp.setVisible(true);
 			}
 		});
@@ -2168,7 +2168,7 @@ public class GUI implements CategoryListener {
 					switch (depthOfNode) {
 					case 1:
 						int dialogResult = JOptionPane.showConfirmDialog(
-								frmCyberPhysical, eraseCategory + nodeName
+								holegJFrame, eraseCategory + nodeName
 										+ "?", warningText,
 								JOptionPane.YES_NO_OPTION);
 						if (dialogResult == JOptionPane.YES_OPTION) {
@@ -2183,27 +2183,27 @@ public class GUI implements CategoryListener {
 						break;
 
 					default:
-						JOptionPane.showMessageDialog(frmCyberPhysical,
+						JOptionPane.showMessageDialog(holegJFrame,
 								selectObjBeforeErase);
 					}
 				} catch (Exception e2) {
 				}
 
 			} else {
-				JOptionPane.showMessageDialog(frmCyberPhysical,
+				JOptionPane.showMessageDialog(holegJFrame,
 						selectObjBeforeErase);
 			}
 			tree.repaint();
 		});
 		toolBar.add(btnDel);
 
-		frmCyberPhysical.getContentPane().add(splitPane);
+		holegJFrame.getContentPane().add(splitPane);
 
 		mntmNew.addActionListener(actionEvent -> {
 			if (model.getObjectsOnCanvas().size() != 0) {
 				int newWarning = JOptionPane.YES_NO_OPTION;
 				int dialogForNewWarning = JOptionPane.showConfirmDialog(
-						frmCyberPhysical, saveBeforeNew, warningText,
+						holegJFrame, saveBeforeNew, warningText,
 						newWarning);
 				if (dialogForNewWarning == JOptionPane.YES_OPTION) {
 					mntmSave.doClick();
@@ -2235,7 +2235,7 @@ public class GUI implements CategoryListener {
 						"Holon Save File(*.holon)", "holon");
 				fileChooser.setFileFilter(holonFilter);
 
-				if (fileChooser.showOpenDialog(frmCyberPhysical) == JFileChooser.APPROVE_OPTION) {
+				if (fileChooser.showOpenDialog(holegJFrame) == JFileChooser.APPROVE_OPTION) {
 					File file = fileChooser.getSelectedFile();
 
 					try {
@@ -2250,7 +2250,7 @@ public class GUI implements CategoryListener {
 						e.printStackTrace();
 						JLabel message = new JLabel(
 								"The savefile is corrupt and cannot be opened.");
-						JOptionPane.showMessageDialog(frmCyberPhysical,
+						JOptionPane.showMessageDialog(holegJFrame,
 								message, "", JOptionPane.ERROR_MESSAGE);
 					}
 				}
@@ -2269,7 +2269,7 @@ public class GUI implements CategoryListener {
 						"Holon Save File(*.holon)", "holon");
 				fileChooser.setFileFilter(holonFilter);
 
-				if (fileChooser.showSaveDialog(frmCyberPhysical) == JFileChooser.APPROVE_OPTION) {
+				if (fileChooser.showSaveDialog(holegJFrame) == JFileChooser.APPROVE_OPTION) {
 					File selectedFile = fileChooser.getSelectedFile();
 					String fileName = selectedFile.getName();
 					String fullPath = fileChooser.getSelectedFile().getPath();
@@ -2288,7 +2288,7 @@ public class GUI implements CategoryListener {
 										+ "\" instead of \".holon\"?");
 
 						int response = JOptionPane.showOptionDialog(
-								frmCyberPhysical, message, "",
+								holegJFrame, message, "",
 								JOptionPane.DEFAULT_OPTION,
 								JOptionPane.QUESTION_MESSAGE, null, options,
 								options[1]);
@@ -2442,7 +2442,7 @@ public class GUI implements CategoryListener {
 		hideScrollGraph();
 		tableHolonElementScrollPane.setBorder(null);
 
-		frmCyberPhysical.getContentPane().add(timePanel, BorderLayout.SOUTH);
+		holegJFrame.getContentPane().add(timePanel, BorderLayout.SOUTH);
 
 
 
@@ -2460,7 +2460,7 @@ public class GUI implements CategoryListener {
 
 		if (nrOfOldSaves > 0) {
 			int dialogButton = JOptionPane.YES_NO_OPTION;
-			int dialogResult = JOptionPane.showConfirmDialog(frmCyberPhysical,
+			int dialogResult = JOptionPane.showConfirmDialog(holegJFrame,
 					"Old autosave file was found, should it be loaded?",
 					warningText, dialogButton);
 			if (dialogResult == JOptionPane.YES_OPTION) {
@@ -2468,7 +2468,7 @@ public class GUI implements CategoryListener {
 					model.setAutoSaveNr(nrOfOldSaves - 1);
 					mntmRedo.doClick();
 				} else {
-					JOptionPane.showMessageDialog(frmCyberPhysical,
+					JOptionPane.showMessageDialog(holegJFrame,
 							"Autosave could not be loaded.");
 					setUpAutoSave(dest);
 				}
@@ -2498,17 +2498,24 @@ public class GUI implements CategoryListener {
 		//Algo
 		JMenuItem openMenu =  new JMenuItem("Open Algorithm Panel", new ImageIcon(Util.loadImage("/Button_Images/iconAlgo.png").getScaledInstance(20, 20, java.awt.Image.SCALE_SMOOTH)));
 		openMenu.addActionListener(actionEvent -> {
-			new AlgoWindow(frmCyberPhysical, controller);
+			new AlgoWindow(holegJFrame, controller);
 		});
-		openMenu.setAccelerator(KeyStroke.getKeyStroke('N', Toolkit.getDefaultToolkit ().getMenuShortcutKeyMask()));
+		openMenu.setAccelerator(KeyStroke.getKeyStroke('N', Toolkit.getDefaultToolkit ().getMenuShortcutKeyMaskEx()));
 		menuWindow.add(openMenu);
 		//Outliner
 		JMenuItem openOutliner =  new JMenuItem("Open Outliner", new ImageIcon(Util.loadImage("/Button_Images/iconOutliner.png").getScaledInstance(20, 20, java.awt.Image.SCALE_SMOOTH)));
 		openOutliner.addActionListener(actionEvent -> {
-			outlinerList.add(new Outliner(frmCyberPhysical, model, controller));
+			outlinerList.add(new Outliner(holegJFrame, model, controller));
 		});
-		openOutliner.setAccelerator(KeyStroke.getKeyStroke('O', Toolkit.getDefaultToolkit ().getMenuShortcutKeyMask()));
+		openOutliner.setAccelerator(KeyStroke.getKeyStroke('O', Toolkit.getDefaultToolkit ().getMenuShortcutKeyMaskEx()));
 		menuWindow.add(openOutliner);
+		//FlexWindow
+		JMenuItem openFlexMenuItem =  new JMenuItem("Open Flexibility Panel", new ImageIcon(Util.loadImage("/Button_Images/iconAlgo.png").getScaledInstance(20, 20, java.awt.Image.SCALE_SMOOTH)));
+		openFlexMenuItem.addActionListener(actionEvent -> {
+			new FlexWindow(holegJFrame, model);
+		});
+		openFlexMenuItem.setAccelerator(KeyStroke.getKeyStroke('F', Toolkit.getDefaultToolkit ().getMenuShortcutKeyMaskEx()));
+		menuWindow.add(openFlexMenuItem);
 	}
 
 
@@ -2538,9 +2545,9 @@ public class GUI implements CategoryListener {
 	}
 
 	private boolean isUpperPanelInsideBounds() {
-		int x = frmCyberPhysical.getX();
-		int y = frmCyberPhysical.getY();
-		int width = frmCyberPhysical.getWidth();
+		int x = holegJFrame.getX();
+		int y = holegJFrame.getY();
+		int width = holegJFrame.getWidth();
 
 		// get all connected screen devices
 		GraphicsDevice[] screenDevices = GraphicsEnvironment
@@ -2587,14 +2594,14 @@ public class GUI implements CategoryListener {
 	private void addObjectAction(String objType,
 			DefaultMutableTreeNode selectedNode) {
 		if (selectedNode == null) {
-			JOptionPane.showMessageDialog(frmCyberPhysical,
+			JOptionPane.showMessageDialog(holegJFrame,
 					"Please select a Category first before adding " + objType
 							+ ".");
 		}
 		// if selected node is a directory for Categories
 		else {
 			if (selectedNode.getLevel() == 1) {
-				String objname = JOptionPane.showInputDialog(frmCyberPhysical,
+				String objname = JOptionPane.showInputDialog(holegJFrame,
 						"Please enter a Name for the " + objType);
 				Category cat = controller.searchCategory(selectedNode
 						.getUserObject().toString());
@@ -2616,7 +2623,7 @@ public class GUI implements CategoryListener {
 				}
 			} else {
 				JOptionPane
-						.showMessageDialog(frmCyberPhysical,
+						.showMessageDialog(holegJFrame,
 								"Objects can not be added to Objects. Please select a Category.");
 			}
 		}
@@ -2668,7 +2675,7 @@ public class GUI implements CategoryListener {
 	 * @return the Frame
 	 */
 	JFrame getFrmCyberPhysical() {
-		return frmCyberPhysical;
+		return holegJFrame;
 	}
 
 	private void refreshLanguages() {