UnitGraph.java 44 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178
  1. package ui.view;
  2. import classes.*;
  3. import classes.comparator.UnitGraphPointComperator;
  4. import interfaces.GraphEditable;
  5. import interfaces.GraphEditable.Graphtype;
  6. import interfaces.IGraphedElement;
  7. import sun.reflect.generics.reflectiveObjects.NotImplementedException;
  8. import ui.controller.Control;
  9. import ui.controller.SingletonControl;
  10. import ui.model.Model;
  11. import javax.swing.*;
  12. import java.awt.*;
  13. import java.awt.event.*;
  14. import java.awt.geom.CubicCurve2D;
  15. import java.awt.geom.GeneralPath;
  16. import java.awt.geom.Line2D;
  17. import java.awt.geom.Path2D;
  18. import java.awt.geom.Point2D;
  19. import java.util.ArrayDeque;
  20. import java.util.ArrayList;
  21. import java.util.Iterator;
  22. import java.util.LinkedList;
  23. import java.util.ListIterator;
  24. /**
  25. * This Class represents a Graph where the User can model the behavior of
  26. * elements and switches over time.
  27. *
  28. * @author Gruppe14
  29. */
  30. public class UnitGraph extends JPanel implements MouseListener, MouseMotionListener, ComponentListener {
  31. private static final long serialVersionUID = 1L;
  32. public static final int STANDARD_GRAPH_ACCURACY = 100;
  33. private GeneralPath graphCurve = new GeneralPath();
  34. private float maximum = 0;
  35. // Information shown when a Point is Dragged
  36. private String dragInformation = "";
  37. // Points
  38. private Point recSize = new Point(8, 8); // Point Size
  39. private Graphics2D g2;
  40. private CubicCurve2D c = new CubicCurve2D.Double();
  41. private CubicCurve2D cr = new CubicCurve2D.Double();
  42. private CubicCurve2D cl = new CubicCurve2D.Double();
  43. private LinkedList<Point> pointList;
  44. // Scale for the Graph
  45. private double scaleX;
  46. private double scaleY;
  47. private double width = -1;
  48. private double height = -1;
  49. private boolean isElement = false;
  50. private boolean isSwitch = false;
  51. private ArrayList<HolonElement> tempElements = new ArrayList<>();
  52. private Model model;
  53. private Control controller;
  54. private Line2D.Double line = null;
  55. private boolean pointDrag = false;
  56. private boolean init = true;
  57. private Point tempP = null;
  58. private double x = 0, y = 0;
  59. private int x1, x2, y1, y2, ctrlx1, ctrly1, ctrlx2, ctrly2;
  60. private int textWidth = 0;
  61. private IGraphedElement current;
  62. //NEW ERA
  63. // Normal Settings
  64. private int border = 4;
  65. private int clickThreshholdSquared = 25;
  66. // Display Settings
  67. /**
  68. * The size of a dot in the graph.
  69. * It should be at least 1.
  70. * */
  71. int dotSize = 8;
  72. /** The Color of a dot in the graph. */
  73. Color dotColor = Color.blue;
  74. //Intern Variables
  75. //TODO: JavaDoc
  76. private LinkedList<UnitGraphPoint> actualGraphPoints = new LinkedList<UnitGraphPoint>();
  77. /**
  78. * This is list is sortet in the y achsis
  79. */
  80. private LinkedList<Position> representativePositions = new LinkedList<Position>();
  81. private Graphtype actualGraphType;
  82. private GraphEditable actualElement;
  83. ListIterator<Position> iter;
  84. ListIterator<UnitGraphPoint> iter2;
  85. Position currentPosition;
  86. private int widthWithBorder, heightWithBorder;
  87. /**
  88. * Constructor.
  89. *
  90. * @param model the Model
  91. * @param control the Controller
  92. */
  93. public UnitGraph(final Model model, Control control) {
  94. setCursor(Cursor.getPredefinedCursor(Cursor.CROSSHAIR_CURSOR));
  95. this.controller = control;
  96. this.model = model;
  97. this.pointList = new LinkedList<>();
  98. this.setBackground(Color.WHITE);
  99. this.addMouseListener(this);
  100. this.addMouseMotionListener(this);
  101. this.addComponentListener(this);
  102. }
  103. /**
  104. * Paints all Components on the Canvas.
  105. *
  106. * @param g Graphics
  107. */
  108. public void paintComponent(Graphics g) {
  109. super.paintComponent(g);
  110. //System.out.println("paint");
  111. Graphics2D g2D = (Graphics2D) g;
  112. g2D.setColor(Color.BLACK);
  113. int höhe = this.getHeight();
  114. int breite = this.getWidth();
  115. g2D.setRenderingHints(new RenderingHints(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON));
  116. g2D.setStroke(new BasicStroke(2));
  117. // g2D.drawLine(0, 0,breite, höhe);
  118. //printDebug();
  119. printDebugRepresentive();
  120. g2D.setColor(dotColor);
  121. drawUnitGraphPoints(g2D);
  122. g2D.setColor(Color.BLACK);
  123. drawUnitGraph(g2D);
  124. //generate Path --> maybe als Methode auslagern
  125. //Good Source for basic understanding for Bezier Curves
  126. //http://www.theappguruz.com/blog/bezier-curve-in-games
  127. Path2D.Double mypath = new Path2D.Double();
  128. Position punktStart = new Position(+40,40);
  129. Position punktEnd = new Position(breite-180,höhe-90);
  130. //Werden Bestimmt
  131. //Erster Punkt bleibt in Höhe gleich aber nimmt die Hälfte der Breite zu
  132. mypath.moveTo(punktStart.x, punktStart.y);
  133. double mitte = (punktStart.x + punktEnd.x)* 0.5;
  134. mypath.curveTo(mitte, punktStart.y, mitte, punktEnd.y, punktEnd.x, punktEnd.y);
  135. g2D.draw(mypath);
  136. g2D.setColor(Color.BLUE);
  137. drawDot(g2D,punktStart);
  138. drawDot(g2D,punktEnd);
  139. // g2 = (Graphics2D) g;
  140. // RenderingHints rh = new RenderingHints(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
  141. // g2.setRenderingHints(rh);
  142. // g2.setStroke(new BasicStroke(0));
  143. //
  144. // graphCurve.reset();
  145. //
  146. // border = (int) recSize.getX() >> 1;
  147. // // Draw the Vertical Lines
  148. // g2.setColor(Color.BLACK);
  149. // for (int i = border; i < this.getWidth() - border; i += border * 2) {
  150. // g2.drawLine(i, border, i, this.getHeight() - border);
  151. // }
  152. // g2.drawLine(this.getWidth() - border, border, this.getWidth() - border, this.getHeight() - border);
  153. //
  154. // for (int i = border; i < this.getHeight() - border; i += border * 2) {
  155. // g2.drawLine(border, i, this.getWidth() - border, i);
  156. // }
  157. // g2.drawLine(border, this.getHeight() - border, this.getWidth() - border, this.getHeight() - border);
  158. //
  159. // int effectiveX;
  160. // if(current!=null)effectiveX=getEffectiveIndex(model, current, model.getCurIteration());
  161. // else effectiveX=0;
  162. //
  163. // if (isElement) {
  164. // // fill array with values from the pointList in a HolonElement
  165. // generateSampleCurves();
  166. //
  167. // if (current != null) {
  168. // // Draw the Lines
  169. // g2.setStroke(new BasicStroke(2));
  170. // g2.setColor(Color.BLACK);
  171. // for (int i = 0; i < pointList.size() - 1; i++) {
  172. // c = buildCurve(pointList.get(i), pointList.get(i + 1));
  173. // c.setCurve((x1 * scaleX) + border, (y1 * scaleY) + border, (ctrlx1 * scaleX) + border,
  174. // (ctrly1 * scaleY) + border, (ctrlx2 * scaleX) + border, (ctrly2 * scaleY) + border,
  175. // (x2 * scaleX) + border, (y2 * scaleY) + border);
  176. // graphCurve.append(c, true);
  177. // }
  178. // g2.draw(graphCurve);
  179. //
  180. // // Draw the Points
  181. // g2.setColor(Color.BLUE);
  182. // for (Point aPointList : pointList) {
  183. // g2.fillOval((int) (aPointList.getX() * scaleX - recSize.getX() / 2) + border,
  184. // (int) (aPointList.getY() * scaleY - recSize.getY() / 2) + border,
  185. // (int) recSize.getX(), (int) recSize.getY());
  186. // }
  187. //
  188. // // Iteration Value
  189. // //TODO: added function getGraphIterations see if it works
  190. // textWidth = g.getFontMetrics().stringWidth("" + ((HolonElement)current).getAvailableEnergyAt(model.getCurIteration())/*arrayOfFloats[effectiveX]*/) + 2;
  191. // if (textWidth
  192. // + (effectiveX) * (this.getWidth() - (border * 2)) / (/*model.getIterations()*/100 - 1) + 2
  193. // + border <= this.getWidth()) {
  194. // g2.drawString("" + ((HolonElement)current).getAvailableEnergyAt(model.getCurIteration()),
  195. // (effectiveX) * (this.getWidth() - (border * 2)) / (/*model.getIterations()*/100 - 1)
  196. // + 2 + border,
  197. // this.getHeight() - 10);
  198. // } else {
  199. // g2.drawString("" + ((HolonElement)current).getAvailableEnergyAt(model.getCurIteration()),
  200. // (effectiveX) * (this.getWidth() - (border * 2)) / (/*model.getIterations()*/100 - 1)
  201. // + border - textWidth,
  202. // this.getHeight() - 10);
  203. // }
  204. //
  205. // }
  206. // // drag Information
  207. // if (tempP != null && pointDrag) {
  208. // dragInformation = "" + convertToValueY(getYValueAt((int) tempP.getX()));
  209. // textWidth = g.getFontMetrics().stringWidth("" + convertToValueY(getYValueAt((int) tempP.getX()))) + 2;
  210. // if (textWidth + (tempP.getX() * scaleX) + 10 + border <= this.getWidth()) {
  211. // g2.drawString(dragInformation, (int) (tempP.getX() * scaleX) + 10 + border,
  212. // (int) (tempP.getY() * scaleY) + 10);
  213. // } else {
  214. // g2.drawString(dragInformation, (int) (tempP.getX() * scaleX) - textWidth,
  215. // (int) (tempP.getY() * scaleY) + 10);
  216. // }
  217. // }
  218. //
  219. // /*
  220. // * // Actual Iteration Point Visualization g2.setColor(Color.RED);
  221. // * if (arrayOfFloats != null) { for (int i = 0; i <
  222. // * arrayOfFloats.length; i++) { g2.fillOval((int) (i * width /
  223. // * (model.getIterations() - 1) * scaleX - recSize.getX() /
  224. // * 2)+border, (int) (convertToCanvasY((int) arrayOfFloats[i]) *
  225. // * scaleY - recSize.getY() / 2)+border, (int) recSize.getX(), (int)
  226. // * recSize.getY()); } }
  227. // */
  228. //
  229. // } else if (isSwitch) {
  230. // if (/*arrayOfBooleans*/current != null) {//Technically this test should be unnecessary
  231. // // array fillen
  232. // fillArrayofBooleans();
  233. //
  234. // // Draw the Lines
  235. // g2.setStroke(new BasicStroke(2));
  236. // g2.setColor(Color.BLACK);
  237. // for (int i = 0; i < pointList.size() - 1; i++) {
  238. // // Left out of bounce
  239. // if ((i == 1 || i == 2) && pointList.get(i).getX() < 0) {
  240. // line = new Line2D.Double(border, pointList.get(i).getY() * scaleY, border,
  241. // pointList.get(i + 1).getY() * scaleY);
  242. // }
  243. // // Right out of bounce
  244. // else if (i == pointList.size() - 4 && pointList.get(pointList.size() - 3).getX() > width) {
  245. // line = new Line2D.Double(pointList.get(i).getX() * scaleX + border,
  246. // pointList.get(i).getY() * scaleY, this.getWidth() - border,
  247. // pointList.get(i + 1).getY() * scaleY);
  248. // } else if (i == pointList.size() - 3 && pointList.get(pointList.size() - 3).getX() > width) {
  249. // line = new Line2D.Double(this.getWidth() - border, pointList.get(i).getY() * scaleY,
  250. // this.getWidth() - border, pointList.get(i + 1).getY() * scaleY);
  251. // } else if (i == pointList.size() - 2 && pointList.get(pointList.size() - 2).getX() > width) {
  252. // line = new Line2D.Double(this.getWidth() - border, pointList.get(i).getY() * scaleY,
  253. // pointList.get(i + 1).getX() * scaleX + border, pointList.get(i + 1).getY() * scaleY);
  254. // } else {
  255. // line = new Line2D.Double(pointList.get(i).getX() * scaleX + border,
  256. // pointList.get(i).getY() * scaleY, pointList.get(i + 1).getX() * scaleX + border,
  257. // pointList.get(i + 1).getY() * scaleY);
  258. // }
  259. // graphCurve.append(line, true);
  260. // }
  261. // g2.draw(graphCurve);
  262. //
  263. // /*
  264. // * // Draw the Points g2.setColor(Color.BLUE); for (int i = 0; i
  265. // * < pointList.size() - 0; i++) { g2.fillOval((int)
  266. // * (pointList.get(i).getX() * scaleX - recSize.getX() / 2) +
  267. // * border, (int) (pointList.get(i).getY() * scaleY -
  268. // * recSize.getY() / 2), (int) recSize.getX(), (int)
  269. // * recSize.getY()); }
  270. // */
  271. //
  272. // // Iteration Value
  273. // g2.setColor(Color.BLUE);
  274. // textWidth = g.getFontMetrics().stringWidth("" + ((HolonSwitch)current).getState(model.getCurIteration())/*arrayOfBooleans[effectiveX]*/) + 2;
  275. // if (textWidth
  276. // + (effectiveX) * (this.getWidth() - (border * 2)) / (/*model.getIterations()*/100 - 1) + 2
  277. // + border <= this.getWidth()) {
  278. // g2.drawString("" + ((HolonSwitch)current).getState(model.getCurIteration()),
  279. // (effectiveX) * (this.getWidth() - (border * 2)) / (/*model.getIterations()*/100 - 1)
  280. // + 2 + border,
  281. // this.getHeight() - 10);
  282. // } else {
  283. // g2.drawString("" + ((HolonSwitch)current).getState(model.getCurIteration()),
  284. // (effectiveX) * (this.getWidth() - (border * 2)) / (/*model.getIterations()*/100 - 1)
  285. // + border - textWidth,
  286. // this.getHeight() - 10);
  287. // }
  288. //
  289. // }
  290. // // When the switch graph is dragged
  291. // if (tempP != null && pointDrag)
  292. //
  293. // {
  294. // try {
  295. // int i;
  296. // for (i = 0; (i * (this.getWidth() - (border * 2)) / (/*model.getIterations()*/100 - 1)
  297. // + border < getMousePosition().getX()); i++) {
  298. // }
  299. // dragInformation = "" + i;
  300. // textWidth = g.getFontMetrics().stringWidth("" + convertToValueY(getYValueAt((int) tempP.getX())))
  301. // + 2;
  302. // if (textWidth + (tempP.getX() * scaleX) + 10 + border <= this.getWidth()) {
  303. // g2.drawString(dragInformation, (int) (getMousePosition().getX()) + 10 + border,
  304. // (int) (getMousePosition().getY() * scaleY) + 10);
  305. // } else {
  306. // g2.drawString(dragInformation, (int) (getMousePosition().getX()) - textWidth,
  307. // (int) (getMousePosition().getY() * scaleY) + 10);
  308. // }
  309. // } catch (Exception e) {
  310. // }
  311. // }
  312. // }
  313. //
  314. // // Iteration Line TODO: repeat
  315. // g2.setColor(Color.BLUE);
  316. // g2.setStroke(new BasicStroke(1));
  317. // g2.drawLine(border + (effectiveX) * (this.getWidth() - border * 2) / /*(model.getIterations() - 1)*/100-1,
  318. // 0, border + (effectiveX) * (this.getWidth() - border * 2) / /*(model.getIterations() - 1)*/100-1,
  319. // this.getHeight());
  320. //
  321. // // algorithmus
  322. // controller.calculateStateForTimeStep(model.getCurIteration());
  323. }
  324. //TODO -> New Section
  325. private void drawDot(Graphics2D g, Position p)
  326. {
  327. g.fillOval(p.x -dotSize/2, p.y-dotSize/2, dotSize, dotSize);
  328. }
  329. private Position convertToPosition(UnitGraphPoint p) {
  330. //Relativ to Border
  331. //1-p.y because its on the Top
  332. return new Position((int) (p.x * widthWithBorder) + border, (int) ((1-p.y) * heightWithBorder) + border);
  333. }
  334. private void drawUnitGraph(Graphics2D g) {
  335. switch(actualGraphType) {
  336. case boolGraph:
  337. drawBoolGraph(g);
  338. break;
  339. case doubleGraph:
  340. drawDoubleGraph(g);
  341. break;
  342. default:
  343. throw new UnsupportedOperationException();
  344. }
  345. }
  346. private void drawUnitGraphPoints(Graphics2D g) {
  347. for(UnitGraphPoint p : actualGraphPoints){
  348. if (p.changed) {
  349. g.setColor(Color.red);
  350. } else {
  351. g.setColor(Color.blue);
  352. }
  353. drawDot(g, p.displayedPosition);
  354. }
  355. }
  356. private void drawBoolGraph(Graphics2D g) {
  357. throw new NotImplementedException();
  358. }
  359. private void updateRepresentativePositions()
  360. {
  361. for(UnitGraphPoint p : actualGraphPoints) {
  362. p.calcDisplayedPosition(border, widthWithBorder, heightWithBorder);
  363. }
  364. }
  365. private void drawDoubleGraph(Graphics2D g) {
  366. }
  367. private void overrideUnitGraph(LinkedList<Point2D.Double> stateCurve) {
  368. actualGraphPoints.clear();
  369. for(Point2D.Double p: stateCurve){
  370. actualGraphPoints.add(new UnitGraphPoint(p));
  371. }
  372. updateRepresentativePositions();
  373. }
  374. private void calculateWidthHeight()
  375. {
  376. widthWithBorder = this.getWidth() - 2 * border;
  377. heightWithBorder = this.getHeight() - 2 * border;
  378. }
  379. public void initNewElement(GraphEditable element)
  380. {
  381. overrideUnitGraph(element.getStateGraph());
  382. actualGraphType = element.getGraphType();
  383. actualElement = element;
  384. repaint();
  385. }
  386. private void printDebug(){
  387. if(actualGraphPoints.isEmpty()) return;
  388. System.out.print("{");
  389. for(UnitGraphPoint p: actualGraphPoints){
  390. System.out.print(p);
  391. }
  392. System.out.println("}");
  393. }
  394. private void printDebugRepresentive(){
  395. if(this.actualGraphPoints.isEmpty()) return;
  396. System.out.print("{");
  397. for(UnitGraphPoint p: actualGraphPoints){
  398. System.out.print(p.displayedPosition);
  399. }
  400. System.out.println("}");
  401. }
  402. private boolean detectPointUnderCurser(MouseEvent mEvent) {
  403. //get mouse Position
  404. Position mPosition = new Position(mEvent.getPoint());
  405. //iter = representativePositions.listIterator();
  406. iter2 = actualGraphPoints.listIterator();
  407. while (iter2.hasNext())
  408. {
  409. Position tempPosition = iter2.next().displayedPosition;
  410. if(mPosition.squareDistance(tempPosition) < clickThreshholdSquared)
  411. {
  412. currentPosition = tempPosition;
  413. return true;
  414. }
  415. }
  416. return false;
  417. }
  418. private void updateGraphPoint(Position newPosition) {
  419. //make it in the bounds of the UnitGraph no Point out of the Border
  420. currentPosition = setInBounds(newPosition);
  421. iter2.set(generateUnitGraphPoint(currentPosition));
  422. repaint();
  423. }
  424. private Position setInBounds(Position p) {
  425. p.clampX(border, border + widthWithBorder);
  426. p.clampY(border, border + heightWithBorder);
  427. return p;
  428. }
  429. private void insertNewGraphPoint(Position pos)
  430. {
  431. System.out.println("insertNewGraphPoint");
  432. setInBounds(pos);
  433. iter2 = actualGraphPoints.listIterator();
  434. while (iter2.hasNext())
  435. {
  436. Position tempPosition = iter2.next().displayedPosition;
  437. if(pos.x <= tempPosition.x)
  438. {
  439. //First previous to go back a position to make the new point before the the Position with greater X
  440. iter2.previous();
  441. iter2.add(generateUnitGraphPoint(pos));
  442. //Second Previous to select the new added Position
  443. iter2.previous();
  444. break;
  445. }
  446. }
  447. }
  448. private UnitGraphPoint generateUnitGraphPoint(Position pos) {
  449. UnitGraphPoint temp = new UnitGraphPoint((double)(pos.x - border)/(double)widthWithBorder,(double)(pos.y - border)/(double)heightWithBorder,true);
  450. temp.displayedPosition = pos;
  451. return temp;
  452. }
  453. @Override
  454. public void mouseDragged(MouseEvent e) {
  455. System.out.println("MouseDragged");
  456. //System.out.println("PositionFromITERATOR= "+ currentPosition +" Index= " + iter.previousIndex() );
  457. updateGraphPoint(new Position(e.getPoint()));
  458. //printDebugRepresentive();
  459. // if (isElement) {
  460. // elementDragged(e);
  461. // } else if (isSwitch) {
  462. // switchDragged(e);
  463. // }
  464. }
  465. /**
  466. * When a Point of a Holon Element is dragged.
  467. *
  468. * @param e MouseEvent
  469. */
  470. public void elementDragged(MouseEvent e) {
  471. System.out.println("elementDragged");
  472. // if (pointDrag && tempP != null) {
  473. // // Out of Bounds verhindern
  474. // int i = pointList.indexOf(tempP);
  475. // x = (e.getX() - border) / scaleX;
  476. // y = (e.getY() - border) / scaleY;
  477. // // y
  478. // if (e.getY() <= border) {
  479. // y = 0;
  480. // } else if (this.getHeight() - border <= e.getY()) {
  481. // y = (this.getHeight() - border * 2) / scaleY;
  482. // }
  483. // // x
  484. // if (tempP == pointList.getFirst() || tempP == pointList.getLast() || pointList.get(i + 1).getX() < x + 2
  485. // || pointList.get(i - 1).getX() > x - 2 || pointList.getFirst().getX() > x - 2
  486. // || pointList.getLast().getX() < x + 2) {
  487. // x = tempP.getX();
  488. // }
  489. // tempP.setLocation(x, y);
  490. //
  491. // repaint();
  492. // }
  493. }
  494. /**
  495. * When a Point of a switch is dragged.
  496. *
  497. * @param e MouseEvent
  498. */
  499. public void switchDragged(MouseEvent e) {
  500. System.out.println("switchDragged");
  501. // if (pointDrag && tempP != null && tempP != pointList.getFirst() && tempP != pointList.getLast()) {
  502. // int i = pointList.indexOf(tempP);
  503. // x = (e.getX() - border) / scaleX;
  504. //
  505. // if (pointList.get(i + 1).getY() == tempP.getY()) {
  506. // // x
  507. // if (pointList.get(i + 1).getX() <= x + 1 || pointList.get(i - 2).getX() >= x - 1) {
  508. // x = tempP.getX();
  509. // }
  510. // pointList.get(i - 1).setLocation(x, pointList.get(i - 1).getY());
  511. // } else {
  512. // // x
  513. // if (pointList.get(i + 2).getX() <= x + 1 || pointList.get(i - 1).getX() >= x - 1) {
  514. // x = tempP.getX();
  515. // }
  516. // pointList.get(i + 1).setLocation(x, pointList.get(i + 1).getY());
  517. // }
  518. // tempP.setLocation(x, tempP.getY());
  519. // repaint();
  520. // }
  521. }
  522. @Override
  523. public void mouseMoved(MouseEvent e) {
  524. }
  525. @Override
  526. public void mouseClicked(MouseEvent e) {
  527. System.out.println("mouseClicked");
  528. }
  529. @Override
  530. public void mouseEntered(MouseEvent e) {
  531. }
  532. @Override
  533. public void mouseExited(MouseEvent e) {
  534. }
  535. @Override
  536. public void mousePressed(MouseEvent e) {
  537. System.out.println("mousePressed");
  538. if (detectPointUnderCurser(e)) {
  539. //DoNothing
  540. } else {
  541. //create new Position
  542. this.insertNewGraphPoint(new Position(e.getPoint()));
  543. repaint();
  544. }
  545. }
  546. /**
  547. * When a point of a Holon Element is pressed.
  548. *
  549. * @param e MouseEvent
  550. */
  551. public void elementPressed(MouseEvent e) {
  552. System.out.println("elementPressed");
  553. //
  554. // boolean added = false;
  555. // boolean deletePoint = false;
  556. //
  557. // int x = (int) ((e.getX() - border) / scaleX);
  558. // double y = (e.getY() - border) / scaleY;
  559. //
  560. // // Click on Point
  561. // tempP = null;
  562. // if (pointList != null) {
  563. // // look if a point was clicked
  564. // for (Point p : pointList) {
  565. // if (x >= p.getX() - recSize.getX() / 2 && y >= p.getY() - recSize.getY() / 2
  566. // && x <= p.getX() + recSize.getX() / 2 && y <= p.getY() * scaleY + recSize.getY() / 2) {
  567. // if (e.getButton() == MouseEvent.BUTTON3) {//TODO: test
  568. // tempP = p;
  569. // deletePoint = true;
  570. // } else {
  571. // pointDrag = true;
  572. // tempP = p;
  573. // }
  574. // }
  575. // }
  576. // // New Point
  577. // if (!pointDrag && e.getButton() != MouseEvent.BUTTON3 && e.getX() != 0
  578. // && e.getX() != this.getWidth() / scaleX) {
  579. // for (int i = 0; i < pointList.size(); i++) {
  580. // // When a point already exist on this x position
  581. // if (x == pointList.get(i).getX() || x == width || x == 0) {
  582. // break;
  583. // }
  584. // if (x < pointList.get(i).getX() && !added) {
  585. // if (e.getY() <= border) {
  586. // pointList.add(i, new Point((int) (x), 0));
  587. // } else {
  588. // pointList.add(i, new Point((int) (x), (int) y));
  589. // }
  590. // added = true;
  591. // pointDrag = true;
  592. // tempP = pointList.get(i);
  593. // }
  594. // }
  595. // }
  596. // // Delete a Point
  597. // if (deletePoint && tempP.getX() != 0
  598. // && /*(*//*tempP.getX() != this.getWidth() / scaleX || */tempP != pointList.getLast())/*)*/ {
  599. // pointList.remove(tempP);
  600. // }
  601. //
  602. // repaint();
  603. // }
  604. }
  605. /**
  606. * When a point of a Switch is pressed.
  607. *
  608. * @param e MouseEvent
  609. */
  610. public void switchPressed(MouseEvent e) {
  611. System.out.println("switchPressed");
  612. boolean added = false;
  613. boolean deletePoint = false;
  614. double x = (e.getX() - border) / scaleX;
  615. e.getY();
  616. // Halbe Iterations Distanz
  617. double dist = (width / (model.getIterations() - 1)) / 2;
  618. // Click on Point
  619. tempP = null;
  620. if (pointList != null) {
  621. for (Point p : pointList) {
  622. if (x >= p.getX() - dist * 2 && x <= p.getX() + dist * 2) {
  623. if (e.getButton() == MouseEvent.BUTTON3) {
  624. tempP = p;
  625. deletePoint = true;
  626. } else {
  627. pointDrag = true;
  628. tempP = p;
  629. }
  630. }
  631. }
  632. // New Point
  633. if (!pointDrag && e.getButton() != MouseEvent.BUTTON3 && x != 0 && x != width) {
  634. for (int i = 0; i < pointList.size() && !added; i++) {
  635. if (x < pointList.get(i).getX() - dist) {
  636. // double p1, p2 um location der points zu bestimmen
  637. double p1 = pointList.get(i - 1).getX();
  638. double p2 = pointList.get(i).getX();
  639. // Punkte hinzufügen, je nachdem ob true oder false
  640. if (pointList.get(i - 1).getY() != (int) (height / 6)
  641. && pointList.get(i).getY() != (int) (height / 6)) {
  642. pointList.add(i, new Point((int) ((x + p2) / 2 + dist), (int) (height - height / 6)));
  643. pointList.add(i, new Point((int) ((x + p2) / 2 + dist), (int) (height / 6)));
  644. pointList.add(i, new Point((int) ((x + p1) / 2 - dist), (int) (height / 6)));
  645. pointList.add(i, new Point((int) ((x + p1) / 2 - dist), (int) (height - height / 6)));
  646. added = true;
  647. } else if (pointList.get(i - 1).getY() == (int) (height / 6)
  648. && pointList.get(i).getY() == (int) (height / 6)) {
  649. pointList.add(i, new Point((int) ((x + p2) / 2 + dist), (int) (height / 6)));
  650. pointList.add(i, new Point((int) ((x + p2) / 2 + dist), (int) (height - height / 6)));
  651. pointList.add(i, new Point((int) ((x + p1) / 2 - dist), (int) (height - height / 6)));
  652. pointList.add(i, new Point((int) ((x + p1) / 2 - dist), (int) (height / 6)));
  653. added = true;
  654. }
  655. }
  656. }
  657. }
  658. // Delete a Point
  659. if (deletePoint && tempP != pointList.getFirst() && tempP != pointList.getLast()) {
  660. int i = pointList.indexOf(tempP);
  661. // If Right, else if Left
  662. if (tempP.getY() == (int) (height / 6) && i < pointList.size() - 1 && i > 0) {
  663. pointList.remove(i);
  664. pointList.remove(i - 1);
  665. pointList.remove(i - 2);
  666. pointList.remove(i - 3);
  667. } else if (tempP.getY() == (int) (height - height / 6)) {
  668. pointList.remove(i + 2);
  669. pointList.remove(i + 1);
  670. pointList.remove(i);
  671. pointList.remove(i - 1);
  672. }
  673. }
  674. repaint();
  675. }
  676. }
  677. @Override
  678. public void mouseReleased(MouseEvent e) {
  679. System.out.println("mouseReleased");
  680. this.actualGraphPoints.sort(new UnitGraphPointComperator());
  681. // if (pointDrag) {
  682. // pointDrag = false;
  683. // tempP = null;
  684. // }
  685. // /**
  686. // * reset the dragInformation.
  687. // */
  688. // dragInformation = "";
  689. // repaint();
  690. }
  691. /**
  692. * When the Component is Resized.
  693. *
  694. * @param e ComponentEvent
  695. */
  696. public void componentResized(ComponentEvent e) {
  697. System.out.println("componentResized");
  698. calculateWidthHeight();
  699. updateRepresentativePositions();
  700. // Wenn ein anderes Element genommen wird
  701. /*
  702. if (init) {
  703. init = false;
  704. // for scale on the first initialisation
  705. if (width == -1 && height == -1) {
  706. width = this.getWidth() - (border * 2);
  707. height = this.getHeight() - (border * 2);
  708. }
  709. // Scale
  710. scaleX = (this.getWidth() - (border * 2)) / width;
  711. scaleY = (this.getHeight() - (border * 2)) / height;
  712. // set the scroll graph invisible
  713. this.getParent().getParent().setVisible(false);
  714. }
  715. // Scale
  716. scaleX = (this.getWidth() - (border * 2)) / width;
  717. scaleY = (this.getHeight() - (border * 2)) / height;
  718. */
  719. repaint();
  720. }
  721. @Override
  722. public void componentHidden(ComponentEvent e) {
  723. }
  724. @Override
  725. public void componentMoved(ComponentEvent e) {
  726. }
  727. @Override
  728. public void componentShown(ComponentEvent e) {
  729. }
  730. /**
  731. * Empty the Graph.
  732. */
  733. public void empty() {
  734. System.out.println("empty");
  735. pointList = null;
  736. tempElements = null;
  737. current = null;
  738. isSwitch = false;
  739. isElement = false;
  740. repaint();
  741. }
  742. /**
  743. * Resets the Points for the Element.
  744. */
  745. public void reset() {
  746. System.out.println("reset");
  747. // pointList.removeAll(pointList);
  748. // if (isSwitch) {
  749. // pointList.addFirst(new Point(-border, (int) (height / 6)));
  750. // pointList.addLast(new Point((int) ((this.getWidth()) / scaleX), (int) (height / 6)));
  751. // } else {
  752. // pointList.addFirst(new Point(0, 0));
  753. // pointList.addLast(new Point((int) ((this.getWidth() - (border * 2)) / scaleX), 0));
  754. // }
  755. // repaint();
  756. }
  757. /**
  758. * converts the number to fit the canvas.
  759. *
  760. * @param d the number to convert
  761. * @return the converted number
  762. */
  763. public double convertToCanvasY(float d) {
  764. System.out.println("convertToCanvasY");
  765. return (height - (d * (height / maximum)));
  766. }
  767. /**
  768. * converts the number to fit the value.
  769. *
  770. * @param d the number to convert
  771. * @return the converted number
  772. */
  773. public float convertToValueY(double d) {
  774. System.out.println("convertToValueY");
  775. return (float) Math.round(((height - (height * (d / height))) / (height / maximum)) * 10) / 10;
  776. }
  777. /**
  778. * Visualize the HolonElement on the Graph.
  779. *
  780. * @param selectedElement which should be visualized
  781. */
  782. public void repaintWithNewElement(ArrayList<HolonElement> selectedElement) {
  783. System.out.println("repaintWithNewElement");
  784. // //maybe linkedlist better?
  785. // //arrayOfFloats = selectedElement.get(selectedElement.size() - 1).getAvailableEnergyPerElementAt();
  786. // current = selectedElement.get(selectedElement.size()-1);
  787. // tempElements=selectedElement;
  788. // pointList = selectedElement.get(selectedElement.size() - 1).getGraphPoints();
  789. // isSwitch = false;
  790. // isElement = true;
  791. // maximum = getMaximum(selectedElement.get(selectedElement.size() - 1));
  792. // // First time clicked on the Element
  793. // if (pointList.isEmpty()) {
  794. // pointList.addFirst(new Point(0, 0));
  795. // pointList.addLast(new Point((int) ((this.getWidth() - (border * 2)) / scaleX), 0));
  796. // }
  797. // repaint();
  798. }
  799. /**
  800. * Visualize the Switch on the Graph.
  801. *
  802. * @param s which should be visualized
  803. */
  804. public void repaintWithNewSwitch(HolonSwitch s) {
  805. System.out.println("repaintWithNewSwitch");
  806. // //arrayOfBooleans = s.getValueArray();
  807. // current=s;
  808. // pointList = s.getGraphPoints();
  809. // isSwitch = true;
  810. // isElement = false;
  811. // // First time clicked on the Element
  812. // if (pointList.isEmpty()) {
  813. // pointList.addFirst(new Point(-border, (int) (height / 6)));
  814. // pointList.addLast(new Point((int) ((this.getWidth()) / scaleX), (int) (height / 6)));
  815. // }
  816. // repaint();
  817. }
  818. /**
  819. * Build a Curve for the Graph.
  820. *
  821. * @param p1 startpoint
  822. * @param p2 endpoint
  823. * @return the CubicCurve2D for the Graph
  824. */
  825. public CubicCurve2D buildCurve(Point p1, Point p2) {
  826. System.out.println("buildCurve");
  827. x1 = (int) p1.getX();
  828. y1 = (int) p1.getY();
  829. x2 = (int) p2.getX();
  830. y2 = (int) p2.getY();
  831. // calculate the controllpoints
  832. ctrlx1 = x1 + (x2 - x1) / 2;
  833. ctrlx2 = x2 - (x2 - x1) / 2;
  834. if (y1 < y2) {
  835. ctrly1 = y1 + (y2 - y1) / 10;
  836. ctrly2 = y2 - (y2 - y1) / 10;
  837. } else {
  838. ctrly1 = y1 - (y1 - y2) / 10;
  839. ctrly2 = y2 + (y1 - y2) / 10;
  840. }
  841. // set the curve
  842. c.setCurve(x1 * scaleX, y1 * scaleY, ctrlx1 * scaleX, ctrly1 * scaleY, ctrlx2 * scaleX, ctrly2 * scaleY,
  843. x2 * scaleX, y2 * scaleY);
  844. return c;
  845. }
  846. /**
  847. * Fills the Arrays with booleans.
  848. */
  849. public void fillArrayofBooleans() {
  850. System.out.println("fillArrayofBooleans");
  851. for (int i = 0; i < STANDARD_GRAPH_ACCURACY; i++) {
  852. int t = (int) getYValueAt((int) (i * width / (STANDARD_GRAPH_ACCURACY - 1)));
  853. if (t <= height / 2) {
  854. ((HolonSwitch)current).setActiveAt(i, true);
  855. } else {
  856. ((HolonSwitch)current).setActiveAt(i, false);
  857. }
  858. }
  859. }
  860. /**
  861. * Fills the Arrays of each HolonElement.
  862. */
  863. @SuppressWarnings("unchecked")
  864. public void generateSampleCurves() {
  865. System.out.println("generateSampleCurves");
  866. for (HolonElement he : tempElements) {
  867. maximum = getMaximum(he);
  868. he.setGraphPoints((LinkedList<Point>) pointList.clone());
  869. //foreach(Point p: pointList)
  870. System.out.println("------------");
  871. System.out.println("pointList[");
  872. for(Point p: pointList)
  873. {
  874. System.out.println(p);
  875. }
  876. System.out.println("]");
  877. for (int i = 0; i < STANDARD_GRAPH_ACCURACY; i++) {//!!!!!
  878. he.setAvailableEnergyPerElementAt(i, convertToValueY(getYValueAt2((int) (i * width / (100 - 1)))));
  879. }
  880. System.out.println("TestgraphPoints:");
  881. he.testFunctiongetAvailableEnergyAt(0);
  882. }
  883. }
  884. /**
  885. * Convert the graph widget point to a pointlist from a holon element
  886. * @param unitgraph
  887. */
  888. public LinkedList<Point> convertUnitGraphToHolonElemntPointList(LinkedList<Point> unitgraph)
  889. {
  890. LinkedList<Point> graphpoints = new LinkedList<Point>();
  891. if(width == 0 || height == 0) return graphpoints;
  892. for(Point p: unitgraph)
  893. {
  894. //CalcX
  895. int x = (int )((p.getX() / width)* 100.0);
  896. //CalcY
  897. int y = (int )((1.0-(p.getY() / height))* 100.0); //1.0- because 0 is at the top, width is at the bottom
  898. //AddPoint
  899. graphpoints.add(new Point(x, y));
  900. }
  901. return graphpoints;
  902. }
  903. public LinkedList<Point> convertHolonElementPointListToUnitGraph(LinkedList<Point> graphPoints)
  904. {
  905. LinkedList<Point> unitgraph = new LinkedList<Point>();
  906. for(Point p: graphPoints)
  907. {
  908. //CalcX
  909. int x = (int )((p.getX() / 100.0)* width);
  910. //CalcY
  911. int y = (int )((1.0-(p.getY() / 100.0))* height); //1.0- because 0 is at the top, width is at the bottom
  912. //AddPoint
  913. unitgraph.add(new Point(x, y));
  914. }
  915. return unitgraph;
  916. }
  917. /**
  918. * Get the Y Value at the x Coordination.
  919. *
  920. * @param xVal the x value for the y value
  921. * @return y, the value at x
  922. */
  923. public float getYValueAt(int xVal) {
  924. System.out.println("getYValueAt");
  925. for (int i = 0; i < pointList.size() - 1; i++) {
  926. // get the Points
  927. if (xVal <= pointList.get(i + 1).getX()) {
  928. // Curve erstellen
  929. Line2D l1 = new Line2D.Double(pointList.get(i).getX(), pointList.get(i).getY(),
  930. pointList.get(i + 1).getX(), pointList.get(i + 1).getY());
  931. Line2D l2 = new Line2D.Double(xVal, 0, xVal, height);
  932. return getIntersectionPoint(l1, l2);
  933. }
  934. }
  935. return 0;
  936. }
  937. /**
  938. * Get y value at the x Coordination via curves.
  939. *
  940. * @param xVal the x value for the y value
  941. * @return y value at x
  942. */
  943. public float getYValueAt2(int xVal) {
  944. System.out.println("getYValueAt2");
  945. for (int i = 0; i < pointList.size() - 1; i++) {
  946. // get the Points
  947. if (xVal >= pointList.get(i).getX()) {
  948. // Curve erstellen
  949. c = buildCurve(pointList.get(i), pointList.get(i + 1));
  950. c.subdivide(cl, cr);
  951. // Teil der Kurve aussuchen
  952. if (cl.getX1() <= xVal * scaleX && cl.getX2() > xVal * scaleX) {
  953. c = cl;
  954. // Kurve Links von "unten"
  955. if (pointList.get(i).getY() >= pointList.get(i + 1).getY()) {
  956. for (float j = (float) (height - 1); j >= 0; j -= 0.1f) {
  957. if (c.contains(xVal * scaleX, j * scaleY)) {
  958. return (float) (j);
  959. }
  960. }
  961. } else {// Kurve Links von "oben"
  962. for (float j = 0; j < height; j += 0.1f) {
  963. if (c.contains(xVal * scaleX, j * scaleY)) {
  964. return (float) (j);
  965. }
  966. }
  967. }
  968. } else {
  969. c = cr;
  970. // Kurve Links von "unten"
  971. if (pointList.get(i).getY() >= pointList.get(i + 1).getY()) {
  972. for (float j = 0; j < height; j += 0.1f) {
  973. if (c.contains(xVal * scaleX, j * scaleY)) {
  974. return (float) (j);
  975. }
  976. }
  977. } else {// Kurve Links von "oben"
  978. for (float j = (float) (height - 1); j >= 0; j -= 0.1f) {
  979. if (c.contains(xVal * scaleX, j * scaleY)) {
  980. return (float) (j);
  981. }
  982. }
  983. }
  984. }
  985. }
  986. }
  987. // else
  988. return getYValueAt(xVal);
  989. }
  990. /**
  991. * Get the Intersection Point of 2 Lines.
  992. *
  993. * @param l1 the first Line
  994. * @param l2 the second Line
  995. * @return The Intersection Point
  996. */
  997. public float getIntersectionPoint(Line2D l1, Line2D l2) {
  998. System.out.println("getIntersectionPoint");
  999. if (!l1.intersectsLine(l2)) {
  1000. return 0;// null;
  1001. }
  1002. double px = l1.getX1(), py = l1.getY1(), rx = l1.getX2() - px, ry = l1.getY2() - py;
  1003. double qx = l2.getX1(), qy = l2.getY1(), sx = l2.getX2() - qx, sy = l2.getY2() - qy;
  1004. double det = sx * ry - sy * rx;
  1005. if (det == 0) {
  1006. return 0;// null;
  1007. } else {
  1008. double z = (sx * (qy - py) + sy * (px - qx)) / det;
  1009. if (z < 0 || z > 1) {
  1010. return 0;// new Point(0, 0); // intersection at end point!
  1011. }
  1012. return (float) (py + z * ry);// new Point((int) (px + z * rx), (int)
  1013. // (py + z * ry));
  1014. }
  1015. } // end intersection line-line
  1016. public void update(ArrayList<AbstractCpsObject> obj) {
  1017. System.out.println("update");
  1018. ArrayDeque<AbstractCpsObject> queue = new ArrayDeque<>();
  1019. AbstractCpsObject u = null;
  1020. queue.addAll(obj);
  1021. while (!queue.isEmpty()) {
  1022. u = queue.pop();
  1023. repaintGraph(u);
  1024. }
  1025. empty();
  1026. if (u instanceof CpsUpperNode)
  1027. for (AbstractCpsObject adjacent : ((CpsUpperNode) u).getNodes()) {
  1028. queue.add(adjacent);
  1029. }
  1030. }
  1031. void repaintGraph(AbstractCpsObject u) {
  1032. System.out.println("repaintGraph");
  1033. ArrayList<HolonElement> list = new ArrayList<>();
  1034. if (u instanceof HolonObject) {
  1035. for (HolonElement ele : ((HolonObject) u).getElements()) {
  1036. list.add(ele);
  1037. repaintWithNewElement(list);
  1038. generateSampleCurves();
  1039. list.remove(0);
  1040. }
  1041. } else if (u instanceof HolonSwitch) {
  1042. repaintWithNewSwitch((HolonSwitch) u);
  1043. fillArrayofBooleans();
  1044. }
  1045. }
  1046. float getMaximum(HolonElement ele) {
  1047. System.out.println("getMaximum");
  1048. if (ele.isFlexible()) {
  1049. return ele.getFlexibleEnergyAvailablePerElement();
  1050. } else {
  1051. return ele.getEnergyPerElement();
  1052. }
  1053. }
  1054. /**
  1055. * sets the localPeriod of the Current Graph
  1056. * @param localPeriod
  1057. */
  1058. public void setLocalPeriod(int localPeriod){
  1059. System.out.println("setLocalPeriod");
  1060. if(isElement)for(IGraphedElement e:tempElements)e.setLocalPeriod(localPeriod);
  1061. else if(isSwitch)current.setLocalPeriod(localPeriod);
  1062. }
  1063. /**
  1064. * gets the LocalPeriod of the CurrentGraph
  1065. * @return localPeriod of the current Element or Switch
  1066. */
  1067. public int getLocalPeriod(){
  1068. System.out.println("getLocalPeriod");
  1069. if(current!=null)return current.getLocalPeriod();
  1070. else return model.getGraphIterations();//TODO: maybe rename
  1071. }
  1072. public boolean isStretching(){
  1073. System.out.println("isStretching");
  1074. return current.isStretching();
  1075. }
  1076. public void setStretching(boolean b){
  1077. System.out.println("setStretching");
  1078. if(isElement)for(IGraphedElement e:tempElements)e.setStretching(b);
  1079. else if(isSwitch)current.setStretching(b);
  1080. }
  1081. }