UnitGraph.java 38 KB

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