UnitGraph.java 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790
  1. package ui.view.main;
  2. import java.awt.BasicStroke;
  3. import java.awt.Color;
  4. import java.awt.Cursor;
  5. import java.awt.Graphics;
  6. import java.awt.Graphics2D;
  7. import java.awt.RenderingHints;
  8. import java.awt.event.ComponentEvent;
  9. import java.awt.event.ComponentListener;
  10. import java.awt.event.MouseEvent;
  11. import java.awt.event.MouseListener;
  12. import java.awt.event.MouseMotionListener;
  13. import java.awt.geom.Path2D;
  14. import java.awt.geom.Point2D;
  15. import java.util.LinkedList;
  16. import java.util.ListIterator;
  17. import javax.swing.JPanel;
  18. import classes.UnitGraphPoint;
  19. import interfaces.GraphEditable;
  20. import interfaces.GraphEditable.Graphtype;
  21. import interfaces.LocalMode;
  22. import ui.controller.Control;
  23. import ui.model.Model;
  24. import utility.Vector2Int;
  25. /**
  26. * This Class represents a Graph where the User can model the behavior of
  27. * elements and switches over time.
  28. *
  29. * @author Tom Troppmann
  30. */
  31. public class UnitGraph extends JPanel implements MouseListener, MouseMotionListener, ComponentListener {
  32. private static final long serialVersionUID = 1L;
  33. // Normal Settings
  34. private int border = 4;
  35. private int clickThreshholdSquared = 25;
  36. // Display Settings
  37. /**
  38. * The size of a dot in the graph.
  39. * It should be at least 1.
  40. * */
  41. int dotSize = 8;
  42. /** The Color of a dot in the graph. */
  43. Color dotColor = Color.blue;
  44. Color editDotColor = new Color(255, 119, 0);
  45. //Intern Variables
  46. private LinkedList<UnitGraphPoint> actualGraphPoints = new LinkedList<UnitGraphPoint>();
  47. private Graphtype actualGraphType = Graphtype.doubleGraph;
  48. private GraphEditable actualElement;
  49. Vector2Int editPosition;
  50. boolean editMode = false;
  51. private enum pointType {Normal, StartPoint, EndPoint};
  52. pointType editPoint = pointType.Normal;
  53. private Model model;
  54. private int widthWithBorder, heightWithBorder;
  55. /**
  56. * Constructor.
  57. *
  58. * @param model the Model
  59. * @param control the Controller
  60. */
  61. public UnitGraph(Control control) {
  62. setCursor(Cursor.getPredefinedCursor(Cursor.CROSSHAIR_CURSOR));
  63. this.model = control.getModel();
  64. this.setBackground(Color.WHITE);
  65. this.addMouseListener(this);
  66. this.addMouseMotionListener(this);
  67. this.addComponentListener(this);
  68. }
  69. /**
  70. * When the UnitGraph should represent a new GraphEditable Element.
  71. * Its Updates the Graph and give access to the Element.
  72. * @param element
  73. */
  74. public void initNewElement(GraphEditable element)
  75. {
  76. overrideUnitGraph(element.getStateGraph());
  77. actualGraphType = element.getGraphType();
  78. actualElement = element;
  79. repaint();
  80. }
  81. /**
  82. * Paints the Graph, the Grid, the actual Line fro the currentIteration
  83. * @param g Graphics
  84. */
  85. public void paintComponent(Graphics g) {
  86. super.paintComponent(g);
  87. Graphics2D g2D = (Graphics2D) g;
  88. drawGrid(g2D);
  89. g2D.setColor(Color.BLACK);
  90. g2D.setRenderingHints(new RenderingHints(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON));
  91. g2D.setStroke(new BasicStroke(2));
  92. drawUnitGraph(g2D);
  93. g2D.setColor(dotColor);
  94. if(editMode)
  95. {
  96. drawUnitGraphPointsReleased(g2D);
  97. }else
  98. {
  99. drawUnitGraphPoints(g2D);
  100. }
  101. g2D.setColor(dotColor);
  102. g2D.setStroke(new BasicStroke(1));
  103. drawCurrentIterartionLine(g2D);
  104. }
  105. // Draw Methods only to let the User see the changes. Nothing its saved here or changed.
  106. /**
  107. * Helper Method to draw the UnitGraphPanel. {@link UnitGraph#paintComponent(Graphics)}
  108. * <p>
  109. * This Methods draws the UnitGraph whether its a boolGraph or a doubleGraph.
  110. * @param g to draw.
  111. */
  112. private void drawUnitGraph(Graphics2D g) {
  113. switch(actualGraphType) {
  114. case boolGraph:
  115. if(editMode)
  116. drawBoolGraphInEditMode(g);
  117. else
  118. drawBoolGraph(g);
  119. break;
  120. case doubleGraph:
  121. if(editMode)
  122. drawDoubleGraphInEditMode(g);
  123. else
  124. drawDoubleGraph(g);
  125. break;
  126. default:
  127. throw new UnsupportedOperationException();
  128. }
  129. }
  130. /**
  131. * Helper Method to draw the UnitGraphPanel. {@link UnitGraph#paintComponent(Graphics)}
  132. * <p>
  133. * This Methods draws the UnitGraphPoints of the UnitGraph.
  134. * @param g to draw.
  135. */
  136. private void drawUnitGraphPoints(Graphics2D g) {
  137. g.setColor(dotColor);
  138. for(UnitGraphPoint p : actualGraphPoints){
  139. drawDot(g, p.displayedPosition);
  140. }
  141. }
  142. /**
  143. * Helper Method to draw the UnitGraphPanel. {@link UnitGraph#paintComponent(Graphics)}
  144. * <p>
  145. * This Methods draws the UnitGraphPoints of the UnitGraph when its in EditMode.
  146. * @param g to draw.
  147. */
  148. private void drawUnitGraphPointsReleased(Graphics2D g) {
  149. drawUnitGraphPoints(g);
  150. g.setColor(editDotColor);
  151. drawDot(g, editPosition);
  152. }
  153. /**
  154. * Helper Method to draw the UnitGraphPanel. {@link UnitGraph#paintComponent(Graphics)}
  155. * <p>
  156. * This Methods draws the Grid on the Canvas.
  157. * @param g2D to draw.
  158. */
  159. private void drawGrid(Graphics2D g2D) {
  160. g2D.setStroke(new BasicStroke(1));
  161. g2D.setColor(Color.lightGray);
  162. int amountOfLines = 10;
  163. int width = widthWithBorder + 2 * border;
  164. int height = heightWithBorder;
  165. for(int i = 0; i<=amountOfLines; i++)
  166. {
  167. int linehieght = (int) (((double)i/ (double) amountOfLines) * (double) height) + border;
  168. g2D.drawLine(0, linehieght, width, linehieght);
  169. }
  170. }
  171. /**
  172. * Helper Method to draw the UnitGraphPanel. {@link UnitGraph#paintComponent(Graphics)}
  173. * <p>
  174. * This Method draws the CurrentIterationLine.
  175. * @param g2D to draw.
  176. */
  177. private void drawCurrentIterartionLine(Graphics2D g)
  178. {
  179. int cur = model.getCurIteration();
  180. int max = model.getIterations();
  181. double where;
  182. if(!this.isUsingLocalPeriod()) {
  183. where = ((double) cur)/((double) max);
  184. }
  185. else
  186. {
  187. int lPeriod = this.getLocalPeriod();
  188. where = ((double) cur%lPeriod)/((double) lPeriod);
  189. }
  190. Vector2Int oben = new Vector2Int(border + (int)(where * widthWithBorder), 0);
  191. Vector2Int unten = new Vector2Int(border + (int)(where * widthWithBorder), 2 * border + heightWithBorder);
  192. drawLine(g,oben,unten);
  193. }
  194. /**
  195. * Helper Method to draw the UnitGraphPanel. {@link UnitGraph#paintComponent(Graphics)}
  196. * <p>
  197. * This Method draws a line between two Positions on the Canvas.
  198. * @param g2D to draw.
  199. * @param start the Position of one end of the line to draw.
  200. * @param end the other Ends Position of the Line to draw.
  201. */
  202. private void drawLine(Graphics2D g, Vector2Int start, Vector2Int end)
  203. {
  204. Path2D.Double path = new Path2D.Double();
  205. path.moveTo(start.getX(), start.getY());
  206. path.lineTo(end.getX(), end.getY());
  207. g.draw(path);
  208. }
  209. /**
  210. * Helper Method to draw the UnitGraphPanel. {@link UnitGraph#paintComponent(Graphics)}
  211. * <p>
  212. * Initialize a Cubic BezierCurve.
  213. * @param start The Position to start the Curve.
  214. */
  215. private Path2D.Double initBezier(Vector2Int start) {
  216. //Good Source for basic understanding for Bezier Curves
  217. //http://www.theappguruz.com/blog/bezier-curve-in-games
  218. Path2D.Double path = new Path2D.Double();
  219. path.moveTo(start.getX(), start.getY());
  220. return path;
  221. }
  222. /**
  223. * Helper Method to draw the UnitGraphPanel. {@link UnitGraph#paintComponent(Graphics)}
  224. * <p>
  225. * Calculate the Path of a the Cubic BezierCurve with the special controlPoints to make the wanted behavior.
  226. * @param path the path of the Bezier.
  227. * @param actaul the actual Position of the Path.
  228. * @param target the end Position of the Curve.
  229. */
  230. private void curveTo(Path2D.Double path, Vector2Int actual, Vector2Int target) {
  231. double mitte = (actual.getX() + target.getX())* 0.5;
  232. path.curveTo(mitte, actual.getY(), mitte, target.getY(), target.getX(), target.getY());
  233. }
  234. /**
  235. * Helper Method to draw the UnitGraphPanel. {@link UnitGraph#paintComponent(Graphics)}
  236. * <p>
  237. * Draws a Dot at a Position.
  238. * @param g to draw.
  239. * @param p the position of the Dot.
  240. */
  241. private void drawDot(Graphics2D g, Vector2Int p)
  242. {
  243. g.fillOval(p.getX() -dotSize/2, p.getY()-dotSize/2, dotSize, dotSize);
  244. }
  245. /**
  246. * Helper Method to draw the UnitGraphPanel. {@link UnitGraph#paintComponent(Graphics)}
  247. * <p>
  248. * This Method draws the UnitGraph as BoolGraph.
  249. * @param g2D to draw.
  250. */
  251. private void drawBoolGraph(Graphics2D g) {
  252. if(actualGraphPoints.size() <= 1) return;
  253. LinkedList<Vector2Int> cornerPoints = new LinkedList<Vector2Int>();
  254. ListIterator<UnitGraphPoint> iter = actualGraphPoints.listIterator();
  255. Vector2Int actual = actualGraphPoints.getFirst().displayedPosition;
  256. Path2D.Double path = new Path2D.Double();
  257. path.moveTo(actual.getX(), actual.getY());
  258. while (iter.hasNext())
  259. {
  260. Vector2Int target = iter.next().displayedPosition;
  261. //BooleanConnection
  262. path.lineTo(target.getX(), actual.getY()); //line to corner
  263. cornerPoints.add(new Vector2Int(target.getX(), actual.getY())); //save corner
  264. path.lineTo(target.getX(), target.getY()); //line to next Point
  265. actual = target;
  266. }
  267. g.draw(path);
  268. //Draw the Points on the Corner that dont exist in Data but should be visual
  269. g.setColor(dotColor);
  270. for(Vector2Int p: cornerPoints)
  271. {
  272. drawDot(g, p);
  273. }
  274. }
  275. /**
  276. * Helper Method to draw the UnitGraphPanel. {@link UnitGraph#paintComponent(Graphics)}
  277. * <p>
  278. * This Method draws the UnitGraph as BoolGraph in EditMode.
  279. * @param g2D to draw.
  280. */
  281. private void drawBoolGraphInEditMode(Graphics2D g) {
  282. LinkedList<Vector2Int> before = new LinkedList<Vector2Int>();
  283. LinkedList<Vector2Int> after = new LinkedList<Vector2Int>();
  284. for(UnitGraphPoint p: actualGraphPoints)
  285. {
  286. if(p.displayedPosition.getX() < editPosition.getX())
  287. before.add(p.displayedPosition);
  288. else
  289. after.add(p.displayedPosition);
  290. }
  291. g.setColor(Color.BLACK);
  292. drawBoolGraphFromList(g, before);
  293. g.setColor(Color.BLACK);
  294. drawBoolGraphFromList(g, after);
  295. //EditGraph
  296. LinkedList<Vector2Int> middle = new LinkedList<Vector2Int>();
  297. if(!before.isEmpty()) middle.add(before.getLast());
  298. middle.add(editPosition);
  299. if(!after.isEmpty()) middle.add(after.getFirst());
  300. g.setColor(editDotColor);
  301. drawBoolGraphFromList(g, middle);
  302. drawSnappingHint(g);
  303. }
  304. /**
  305. * Helper Method to draw the UnitGraphPanel. {@link UnitGraph#paintComponent(Graphics)}
  306. * <p>
  307. * This Method draws a red Hint to signal the User the snapping of the hovered Point under the Cursor in EditMode.
  308. * @param g2D to draw.
  309. */
  310. private void drawSnappingHint(Graphics2D g)
  311. {
  312. //ColorHint
  313. g.setColor(Color.RED);
  314. //Threshhold Line
  315. final float dash1[] = {10.0f};
  316. final BasicStroke dashed =new BasicStroke(2.0f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER, 10.0f, dash1, 0.0f);
  317. g.setStroke(dashed);
  318. int halfheight = border + heightWithBorder / 2;
  319. g.drawLine(0, halfheight , widthWithBorder + 2 * border, halfheight);
  320. //Threshhold Text
  321. g.drawString("Snapping Threshold", 10, halfheight - 2);
  322. }
  323. /**
  324. * Helper Method to draw the UnitGraphPanel. {@link UnitGraph#paintComponent(Graphics)}
  325. * <p>
  326. * This Method draws a partial Graph from a Position List as BoolGraph.
  327. * @param g2D to draw.
  328. * @param list the PositionList to draw a BoolGraph
  329. */
  330. private void drawBoolGraphFromList(Graphics2D g, LinkedList<Vector2Int> list) {
  331. if(list.size() <= 1) return;
  332. ListIterator<Vector2Int> iter = list.listIterator();
  333. LinkedList<Vector2Int> cornerPoints = new LinkedList<Vector2Int>();
  334. Vector2Int actual = list.getFirst();
  335. Path2D.Double path = new Path2D.Double();
  336. path.moveTo(actual.getX(), actual.getY());
  337. while (iter.hasNext())
  338. {
  339. Vector2Int target = iter.next();
  340. //BooleanConnection
  341. path.lineTo(target.getX(), actual.getY()); //line to corner
  342. cornerPoints.add(new Vector2Int(target.getX(), actual.getY())); //save corner
  343. path.lineTo(target.getX(), target.getY()); //line to next Point
  344. actual = target;
  345. }
  346. g.draw(path);
  347. g.setColor(dotColor);
  348. for(Vector2Int p: cornerPoints)
  349. {
  350. drawDot(g, p);
  351. }
  352. }
  353. /**
  354. * Helper Method to draw the UnitGraphPanel. {@link UnitGraph#paintComponent(Graphics)}
  355. * <p>
  356. * This Method draws the UnitGraph as DoubleGraph.
  357. * @param g2D to draw.
  358. */
  359. private void drawDoubleGraph(Graphics2D g) {
  360. if(actualGraphPoints.isEmpty()) return;//throw new IndexOutOfBoundsException("A Graph Without Points is not supportet jet");
  361. ListIterator<UnitGraphPoint> iter = actualGraphPoints.listIterator();
  362. Vector2Int actual = iter.next().displayedPosition;
  363. Path2D.Double path = this.initBezier(actual);
  364. while (iter.hasNext())
  365. {
  366. Vector2Int target = iter.next().displayedPosition;
  367. this.curveTo(path, actual, target);
  368. actual = target;
  369. }
  370. g.draw(path);
  371. }
  372. /**
  373. * Helper Method to draw the UnitGraphPanel. {@link UnitGraph#paintComponent(Graphics)}
  374. * <p>
  375. * This Method draws the UnitGraph as DoubleGraph in EditMode.
  376. * @param g2D to draw.
  377. */
  378. private void drawDoubleGraphInEditMode(Graphics2D g) {
  379. LinkedList<Vector2Int> before = new LinkedList<Vector2Int>();
  380. LinkedList<Vector2Int> after = new LinkedList<Vector2Int>();
  381. for(UnitGraphPoint p: actualGraphPoints)
  382. {
  383. if(p.displayedPosition.getX() < editPosition.getX())
  384. before.add(p.displayedPosition);
  385. else
  386. after.add(p.displayedPosition);
  387. }
  388. drawUnitGraphFromList(g, before);
  389. drawUnitGraphFromList(g, after);
  390. //EditGraph
  391. LinkedList<Vector2Int> middle = new LinkedList<Vector2Int>();
  392. if(!before.isEmpty()) middle.add(before.getLast());
  393. middle.add(editPosition);
  394. if(!after.isEmpty()) middle.add(after.getFirst());
  395. g.setColor(editDotColor);
  396. drawUnitGraphFromList(g, middle);
  397. }
  398. /**
  399. * Helper Method to draw the UnitGraphPanel. {@link UnitGraph#paintComponent(Graphics)}
  400. * <p>
  401. * This Method draws a partial Graph from a Position List as DoubleGraph.
  402. * @param g2D to draw.
  403. * @param list the PositionList to draw a DoubleGraph
  404. */
  405. private void drawUnitGraphFromList(Graphics2D g, LinkedList<Vector2Int> list) {
  406. if(list.size() <= 1) return;
  407. ListIterator<Vector2Int> iter = list.listIterator();
  408. Vector2Int actual = list.getFirst();
  409. Path2D.Double path = this.initBezier(actual);
  410. while (iter.hasNext())
  411. {
  412. Vector2Int target = iter.next();
  413. curveTo(path, actual, target);
  414. actual = target;
  415. }
  416. g.draw(path);
  417. }
  418. //Under the hood functions to calculate and function the
  419. /**
  420. * A unitgraphpoint have a x and y position to store the data of a graph point.
  421. * Also it have a displayposition to store the Position of the GraphPoints on the Canvas.
  422. * e.g. when the canvas has 500 width and 200 height a GraphPoint with the X=0.5 and Y=1.0 should have a displayposition of (250,3) when border is 3.
  423. */
  424. private void updateRepresentativePositions()
  425. {
  426. for(UnitGraphPoint p : actualGraphPoints) {
  427. p.calcDisplayedPosition(border, widthWithBorder, heightWithBorder);
  428. }
  429. }
  430. /**
  431. * Takes a List of GraphPoints and convert it to the actual UnitGraphPoints with displayposition in the {@link #actualGraphPoints}
  432. * @param stateCurve the list of GraphPoint
  433. */
  434. private void overrideUnitGraph(LinkedList<Point2D.Double> stateCurve) {
  435. actualGraphPoints.clear();
  436. for(Point2D.Double p: stateCurve){
  437. actualGraphPoints.add(new UnitGraphPoint(p));
  438. }
  439. updateRepresentativePositions();
  440. }
  441. /**
  442. * When the PanelSize Change the width and height to calculate the drawings have to be adjusted.
  443. */
  444. private void calculateWidthHeight()
  445. {
  446. widthWithBorder = this.getWidth() - 2 * border;
  447. heightWithBorder = this.getHeight() - 2 * border;
  448. }
  449. /**
  450. * Save the actualGraphPoint List to the GraphEditable Element.
  451. */
  452. private void saveGraph() {
  453. LinkedList<Point2D.Double> actual = actualElement.getStateGraph();
  454. actual.clear();
  455. for(UnitGraphPoint p: actualGraphPoints)
  456. {
  457. actual.add(p.getPoint());
  458. }
  459. actualElement.sampleGraph();
  460. }
  461. /**
  462. * Remove a UnitGraphPoint from the UnitGraphPoint list ({@link #actualGraphPoints} when its near a given Position.
  463. * @param mPosition
  464. */
  465. private void removePointNearPosition(Vector2Int mPosition) {
  466. ListIterator<UnitGraphPoint> iter = actualGraphPoints.listIterator();
  467. while (iter.hasNext())
  468. {
  469. if(near(mPosition,iter.next().displayedPosition))
  470. {
  471. iter.remove();
  472. break;
  473. }
  474. }
  475. }
  476. /**
  477. * Determine if the Point is a StartPoint , EndPoint or a NormalPoint a.k.a. in between Points.
  478. * @param mPosition The Position to check.
  479. */
  480. private void detectStartEndPoint(Vector2Int mPosition)
  481. {
  482. UnitGraphPoint first = actualGraphPoints.getFirst();
  483. UnitGraphPoint last = actualGraphPoints.getLast();
  484. if(near(mPosition, first.displayedPosition)) editPoint = pointType.StartPoint;
  485. else if(near(mPosition, last.displayedPosition)) editPoint = pointType.EndPoint;
  486. else editPoint = pointType.Normal;
  487. }
  488. /**
  489. * Determine if a Point is near the Cursor (depends on Mode what near means). To detect if it should grab the Point or create a new Point.
  490. * @param actual
  491. * @param target
  492. * @return
  493. */
  494. private boolean near(Vector2Int actual, Vector2Int target) {
  495. switch(actualGraphType)
  496. {
  497. case boolGraph: //Distance only with X
  498. int xDis = target.getX() - actual.getX();
  499. return xDis * xDis < clickThreshholdSquared;
  500. case doubleGraph:
  501. return actual.getSquaredDistance(target) < clickThreshholdSquared;
  502. default:
  503. return false;
  504. }
  505. }
  506. /**
  507. * When the Mouse Drag a Point it updates each time the position.
  508. * @param newPosition
  509. */
  510. private void updateEditPointPosition(Vector2Int newPosition) {
  511. //make it in the bounds of the UnitGraph no Point out of the Border
  512. Vector2Int currentPosition = setInBounds(newPosition);
  513. if(editPoint != pointType.Normal) attachToBorder(currentPosition);
  514. if(actualGraphType == Graphtype.boolGraph) snapBoolean(currentPosition);
  515. this.editPosition = currentPosition;
  516. }
  517. /**
  518. * No Point on the UnitGraph should exit the UnitGraph.
  519. * @param p the Position
  520. * @return the updated Position.
  521. */
  522. private Vector2Int setInBounds(Vector2Int p) {
  523. p.clampX(border, border + widthWithBorder);
  524. p.clampY(border, border + heightWithBorder);
  525. return p;
  526. }
  527. /**
  528. * For Switches the Point have to be Snap to the Top or the Bottem.
  529. * @param p the Position
  530. * @return the updated Position.
  531. */
  532. private Vector2Int snapBoolean(Vector2Int p)
  533. {
  534. if (p.getY() < border + heightWithBorder / 2) {
  535. p.setY(border);
  536. } else {
  537. p.setY(border + heightWithBorder);
  538. }
  539. return p;
  540. }
  541. /**
  542. * The First Point has to be at 0(LeftSide) and Last Point has to be at 1(RightSide).
  543. * @param p the Position
  544. * @return the updated Position.
  545. */
  546. private Vector2Int attachToBorder(Vector2Int p)
  547. {
  548. switch(editPoint)
  549. {
  550. case StartPoint:
  551. p.setX(border);
  552. break;
  553. case EndPoint:
  554. p.setX(border + widthWithBorder);
  555. break;
  556. default:
  557. break;
  558. }
  559. return p;
  560. }
  561. /**
  562. * Insert a Position in the UnitGraphList at the right order.
  563. * Its sorted based on the xValues.
  564. * @param pos The new UnitGraphPoints Position
  565. */
  566. private void insertNewGraphPoint(Vector2Int pos)
  567. {
  568. setInBounds(pos);
  569. ListIterator<UnitGraphPoint> iter2 = actualGraphPoints.listIterator();
  570. while (iter2.hasNext())
  571. {
  572. Vector2Int tempPosition = iter2.next().displayedPosition;
  573. if(pos.getX() <= tempPosition.getX())
  574. {
  575. //previous to go back a position to make the new point before the the Position with greater X
  576. iter2.previous();
  577. iter2.add(generateUnitGraphPoint(pos));
  578. break;
  579. }
  580. }
  581. if(!iter2.hasNext()) //if behind last point
  582. {
  583. iter2.add(generateUnitGraphPoint(pos));
  584. }
  585. }
  586. /**
  587. * Generate a UnitGraphPoint from a normal Position in the UnitGraph.
  588. * @param pos the normal pos with xValues from 0..Width and yValues from 0..Height
  589. * @return a UnitGraphPoint
  590. */
  591. private UnitGraphPoint generateUnitGraphPoint(Vector2Int pos) {
  592. UnitGraphPoint temp = new UnitGraphPoint((double) (pos.getX() - border) / (double) widthWithBorder,
  593. 1 - (double) (pos.getY() - border) / (double) heightWithBorder, true);
  594. temp.displayedPosition = pos;
  595. return temp;
  596. }
  597. /**
  598. * Update the Point Position
  599. */
  600. @Override
  601. public void mouseDragged(MouseEvent e) {
  602. updateEditPointPosition(new Vector2Int(e.getPoint().x, e.getPoint().y));
  603. repaint();
  604. }
  605. @Override
  606. public void mouseMoved(MouseEvent e) {
  607. }
  608. @Override
  609. public void mouseClicked(MouseEvent e) {
  610. }
  611. @Override
  612. public void mouseEntered(MouseEvent e) {
  613. }
  614. @Override
  615. public void mouseExited(MouseEvent e) {
  616. }
  617. /**
  618. * The First Step.
  619. * When LeftMouseButton its checks if a point is to grab under the cursor or create a new Point. Then enter EditMode.
  620. * When RightMouseButton its delete a point if its under the Curser.
  621. */
  622. @Override
  623. public void mousePressed(MouseEvent e) {
  624. Vector2Int mPosition = new Vector2Int(e.getPoint().x, e.getPoint().y);
  625. if (e.getButton() == MouseEvent.BUTTON3) {
  626. // RightMouseButtonEvent
  627. detectStartEndPoint(mPosition);
  628. if (editPoint == pointType.Normal) {
  629. removePointNearPosition(mPosition);
  630. repaint();
  631. }
  632. editMode = false;
  633. } else if (e.getButton() == MouseEvent.BUTTON1) {
  634. // LeftMouseButtonEvent
  635. detectStartEndPoint(mPosition);
  636. removePointNearPosition(mPosition);
  637. updateEditPointPosition(mPosition);
  638. editMode = true;
  639. repaint();
  640. }
  641. }
  642. /**
  643. * The last step to save the Changes.
  644. * Its insert the Hovering Point and exit EditMode.
  645. */
  646. @Override
  647. public void mouseReleased(MouseEvent e) {
  648. if(editMode)
  649. {
  650. this.insertNewGraphPoint(editPosition);
  651. editMode = false;
  652. repaint();
  653. }
  654. saveGraph();
  655. }
  656. /**
  657. * When the Component is Resized.
  658. *
  659. * @param e ComponentEvent
  660. */
  661. public void componentResized(ComponentEvent e) {
  662. calculateWidthHeight();
  663. updateRepresentativePositions();
  664. repaint();
  665. }
  666. @Override
  667. public void componentHidden(ComponentEvent e) {
  668. }
  669. @Override
  670. public void componentMoved(ComponentEvent e) {
  671. }
  672. @Override
  673. public void componentShown(ComponentEvent e) {
  674. }
  675. /**
  676. * Resets the graph to normal.
  677. */
  678. public void reset() {
  679. if(this.actualElement != null) {
  680. actualElement.reset();
  681. overrideUnitGraph(actualElement.getStateGraph());
  682. repaint();
  683. }
  684. }
  685. //LocalMode access methods...
  686. //To access a element from the GUI for the LocalMode
  687. public void setUseLocalPeriod(boolean state) {
  688. if(this.actualElement != null) {
  689. ((LocalMode) actualElement).setUseLocalPeriod(state);
  690. }
  691. }
  692. public void setLocalPeriod(int localLength) {
  693. if(this.actualElement != null) {
  694. ((LocalMode) actualElement).setLocalPeriod(localLength);
  695. }
  696. }
  697. public int getLocalPeriod() {
  698. if(this.actualElement != null) {
  699. return ((LocalMode) actualElement).getLocalPeriod();
  700. }
  701. return -1;
  702. }
  703. public boolean isUsingLocalPeriod() {
  704. if(this.actualElement != null) {
  705. return ((LocalMode) actualElement).isUsingLocalPeriod();
  706. }
  707. return false;
  708. }
  709. }