Tom 5 years ago
parent
commit
ca01444699
1 changed files with 494 additions and 0 deletions
  1. 494 0
      src/exampleAlgorithms/DemoAlgo.java

+ 494 - 0
src/exampleAlgorithms/DemoAlgo.java

@@ -0,0 +1,494 @@
+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.DecoratedNetwork;
+import ui.model.DecoratedState;
+import ui.model.Model;
+
+public class DemoAlgo 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;
+		//Windrad
+		private HolonObject windrad;
+		
+		
+		private int waitDurationWindradStep = 400;
+		private int waitDurationEnd = 1000;
+
+		int counter;
+		
+		
+		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 DemoAlgo() {
+			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);
+			
+			
+//			JCheckBox switchesCheckBox = new JCheckBox();
+//			switchesCheckBox.setSelected(closeSwitches);
+//			switchesCheckBox.setBounds(370, 60, 25, 20);
+//			switchesCheckBox.addActionListener(actionEvent -> closeSwitches = switchesCheckBox.isSelected());
+//			parameterPanel.add(switchesCheckBox);
+			
+			JButton selectRoom1Button = new JButton("Select");
+			selectRoom1Button.setBounds(10,300, 90, 20);
+			selectRoom1Button.addActionListener(actionEvent -> this.selectHolonObject());
+			parameterPanel.add(selectRoom1Button);
+			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);
+			JFormattedTextField betweenTF = new JFormattedTextField(integerFormatter);
+			betweenTF.setText(""+waitDurationWindradStep);
+			betweenTF.setBounds(80 ,330, 80, 30);
+			betweenTF.addPropertyChangeListener(propertyChange ->{
+				String text = betweenTF.getValue().toString();
+				text = text.replaceAll("\\s", "");
+				waitDurationWindradStep = Integer.parseInt((text));
+			});
+			parameterPanel.add(betweenTF);
+			JLabel afterLabel = new JLabel("after:");
+			afterLabel.setBounds(10, 360, 70, 30);
+			parameterPanel.add(afterLabel);
+			JFormattedTextField afterTF = new JFormattedTextField(integerFormatter);
+			afterTF.setText(""+waitDurationEnd);
+			afterTF.setBounds(80 ,360, 80, 30);
+			afterTF.addPropertyChangeListener(propertyChange ->{
+				String text = afterTF.getValue().toString();
+				text = text.replaceAll("\\s", "");
+				waitDurationEnd = Integer.parseInt((text));
+			});
+			parameterPanel.add(afterTF);
+			
+			
+			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();
+			counter = 0;
+			int actualIteration = control.getModel().getCurIteration();
+			deactivateWindrad();
+			setAllSwitchesClosed();
+			updateVisual();
+			
+			try {
+				//Schalte Slow das Windrad Ein
+				if(windrad == null)return;
+				for(int i = 0; i< windrad.getNumberOfElements(); i++) {
+					windrad.getElements().get(i).setActive(true);
+					TimeUnit.MILLISECONDS.sleep(waitDurationWindradStep);
+					updateVisual();
+				}
+				TimeUnit.MILLISECONDS.sleep(waitDurationEnd);
+			} catch (InterruptedException e) {
+			}
+			
+			setHolonElemntsAktiv(actualIteration);
+			println("Changed Elements: " + counter);
+			updateVisual();
+		}
+
+		
+		
+
+			
+		
+		private void deactivateWindrad() {
+			if(windrad == null)return;
+			windrad.getElements().stream().forEach(ele -> ele.setActive(false));
+		}
+		private void setHolonElemntsAktiv(int actualIteration) {
+			for(int i = 0;i<access.size();i++) {
+				AccessWrapper aw = access.get(i);
+				if(aw.getState(actualIteration) ==false) counter++;
+				if(aw.getType() == AccessWrapper.HOLONELEMENT) aw.setState(true);
+			}
+		}
+		private void setAllSwitchesClosed() {
+			for(HolonSwitch hSwitch : switchList) {
+				if(hSwitch.getManualMode() == false) counter++;
+				hSwitch.setManualMode(true);
+				hSwitch.setManualState(true);
+			}
+			
+		}
+		/**
+		 * 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();
+		}
+		/**
+		 * 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 selectHolonObject() {
+			List<HolonObject> holonObjectList = new ArrayList<HolonObject>();
+			addObjectToList(control.getModel().getObjectsOnCanvas(),holonObjectList);
+			Object[] possibilities = holonObjectList.stream().map(aCps -> new Handle<HolonObject>(aCps)).toArray();
+			@SuppressWarnings("unchecked")
+			Handle<HolonObject> selected = (Handle<HolonObject>) JOptionPane.showInputDialog(content, "Select HolonObject:", "HolonObject?",  JOptionPane.OK_OPTION,new ImageIcon(new BufferedImage(1, 1, BufferedImage.TYPE_INT_ARGB)) , possibilities, "");
+			if(selected != null) {
+				//println("Selected: " + selected);
+				windrad = selected.object;
+			}
+		}
+
+
+
+
+		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();
+			}
+		}
+
+}