MyCanvas.java 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495
  1. package ui.view;
  2. import java.awt.BasicStroke;
  3. import java.awt.Color;
  4. import java.awt.Graphics;
  5. import java.awt.Graphics2D;
  6. import java.awt.Image;
  7. import java.awt.Rectangle;
  8. import java.awt.RenderingHints;
  9. import java.awt.event.ActionEvent;
  10. import java.awt.event.ActionListener;
  11. import java.awt.event.MouseEvent;
  12. import java.awt.event.MouseListener;
  13. import java.awt.event.MouseMotionListener;
  14. import java.awt.geom.Line2D;
  15. import java.io.File;
  16. import java.util.ArrayList;
  17. import java.util.Timer;
  18. import java.util.TimerTask;
  19. import javax.swing.ImageIcon;
  20. import javax.swing.JMenuItem;
  21. import javax.swing.JPanel;
  22. import javax.swing.JPopupMenu;
  23. import javax.swing.JToolTip;
  24. import classes.CpsEdge;
  25. import classes.CpsNode;
  26. import classes.CpsObject;
  27. import classes.HolonElement;
  28. import classes.HolonObject;
  29. import classes.HolonSwitch;
  30. import ui.controller.Control;
  31. import ui.model.*;
  32. class MyCanvas extends JPanel implements MouseListener, MouseMotionListener {
  33. private Image img = null; // Contains the image to draw on MyCanvas
  34. private int x = 0;
  35. private int y = 0;
  36. // edge Object Start Point
  37. private Model model;
  38. private final Control controller;
  39. Graphics2D g2; // For Painting
  40. private int cx;
  41. private int cy;
  42. ArrayList<HolonElement> dataSelected = new ArrayList<HolonElement>();
  43. private boolean dragging = false; // for dragging
  44. private boolean drawEdge = false; // for drawing edges
  45. private boolean click = false; // for double click
  46. public CpsObject tempCps = null;
  47. private Rectangle selectRect = new Rectangle();
  48. private CpsEdge edgeHighlight = null;
  49. // PopUpMenu
  50. private JPopupMenu popmenu = new JPopupMenu();
  51. private JMenuItem itemDelete = new JMenuItem("Delete Object");
  52. private JToolTip objectTT = new JToolTip();
  53. public MyCanvas(final Model model, Control control) {
  54. this.add(objectTT);
  55. this.controller = control;
  56. this.model = model;
  57. popmenu.add(itemDelete);
  58. itemDelete.setEnabled(false);
  59. itemDelete.addActionListener(new ActionListener() {
  60. @Override
  61. public void actionPerformed(ActionEvent e) {
  62. // Remove the selected Object object
  63. controller.deleteObjectOnCanvas(tempCps);
  64. tempCps = null;
  65. selectRect.setRect(0, 0, 0, 0);
  66. repaint();
  67. }
  68. });
  69. this.addMouseListener(this);
  70. this.addMouseMotionListener(this);
  71. }
  72. /**
  73. * Paints all Components on the Canvas
  74. *
  75. * @param Graphics
  76. *
  77. */
  78. public void paintComponent(Graphics g) {
  79. super.paintComponent(g);
  80. // Rendering
  81. g2 = (Graphics2D) g;
  82. RenderingHints rh = new RenderingHints(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
  83. g2.setRenderingHints(rh);
  84. // Selection
  85. if (selectRect != null) {
  86. g2.setColor(Color.GREEN);
  87. g2.fillRect((int) selectRect.getX(), (int) selectRect.getY(), (int) selectRect.getWidth(),
  88. (int) selectRect.getHeight());
  89. }
  90. // drawEdges
  91. g2.setColor(Color.BLACK);
  92. g2.setStroke(new BasicStroke(2));
  93. if (drawEdge)
  94. g2.drawLine(tempCps.getPosition().x + controller.getScaleDiv2(),
  95. tempCps.getPosition().y + controller.getScaleDiv2(), x, y);
  96. for (CpsEdge con : model.getEdgesOnCanvas()) {
  97. if (con.getA().getID() != model.getSelectedObjectID() && con.getB().getID() != model.getSelectedObjectID()
  98. && con != edgeHighlight) {
  99. g2.drawLine(con.getA().getPosition().x + controller.getScaleDiv2(),
  100. con.getA().getPosition().y + controller.getScaleDiv2(),
  101. con.getB().getPosition().x + controller.getScaleDiv2(),
  102. con.getB().getPosition().y + controller.getScaleDiv2());
  103. g2.drawString(con.getFlow() + "/" + con.getCapacity(),
  104. (con.getA().getPosition().x + con.getB().getPosition().x) / 2 + controller.getScaleDiv2(),
  105. (con.getA().getPosition().y + con.getB().getPosition().y) / 2 + controller.getScaleDiv2());
  106. }
  107. }
  108. // Highlighted Edge
  109. if (model.getSelectedObjectID() > 0) {
  110. g2.setColor(Color.GREEN);
  111. for (CpsEdge con : model.getEdgesOnCanvas()) {
  112. if (con.getA().getID() == model.getSelectedObjectID()
  113. || con.getB().getID() == model.getSelectedObjectID() && con != edgeHighlight) {
  114. g2.drawLine(con.getA().getPosition().x + controller.getScaleDiv2(),
  115. con.getA().getPosition().y + controller.getScaleDiv2(),
  116. con.getB().getPosition().x + controller.getScaleDiv2(),
  117. con.getB().getPosition().y + controller.getScaleDiv2());
  118. g2.drawString(con.getFlow() + "/" + con.getCapacity(),
  119. (con.getA().getPosition().x + con.getB().getPosition().x) / 2 + controller.getScaleDiv2(),
  120. (con.getA().getPosition().y + con.getB().getPosition().y) / 2 + controller.getScaleDiv2());
  121. }
  122. }
  123. } else if (edgeHighlight != null) {
  124. g2.setColor(Color.GREEN);
  125. g2.drawLine(edgeHighlight.getA().getPosition().x + controller.getScaleDiv2(),
  126. edgeHighlight.getA().getPosition().y + controller.getScaleDiv2(),
  127. edgeHighlight.getB().getPosition().x + controller.getScaleDiv2(),
  128. edgeHighlight.getB().getPosition().y + controller.getScaleDiv2());
  129. g2.drawString(edgeHighlight.getFlow() + "/" + edgeHighlight.getCapacity(),
  130. (edgeHighlight.getA().getPosition().x + edgeHighlight.getB().getPosition().x) / 2
  131. + controller.getScaleDiv2(),
  132. (edgeHighlight.getA().getPosition().y + edgeHighlight.getB().getPosition().y) / 2
  133. + controller.getScaleDiv2());
  134. }
  135. // Objects
  136. for (CpsObject cps : model.getObjectsOnCanvas()) {
  137. File checkPath = new File(cps.getImage());
  138. if (checkPath.exists()) {
  139. img = new ImageIcon(cps.getImage()).getImage();
  140. } else {
  141. img = new ImageIcon(this.getClass().getResource(cps.getImage())).getImage();
  142. }
  143. g2.drawImage(img, cps.getPosition().x, cps.getPosition().y, controller.getScale(), controller.getScale(),
  144. null);
  145. }
  146. }
  147. @Override
  148. public void mouseClicked(MouseEvent e) {
  149. // If double clicked on a Switch change the Image to on/off
  150. if (doubleClick() && tempCps != null && tempCps.getClass() == HolonSwitch.class) {
  151. System.out.println("trans double click");
  152. if (tempCps.getImage().compareTo("/Images/switch-on.png") == 0) {
  153. tempCps.setImage("/Images/switch-off.png");
  154. } else {
  155. tempCps.setImage("/Images/switch-on.png");
  156. }
  157. }
  158. repaint();
  159. }
  160. @Override
  161. public void mouseEntered(MouseEvent e) {
  162. // TODO Auto-generated method stub
  163. }
  164. @Override
  165. public void mouseExited(MouseEvent e) {
  166. // TODO Auto-generated method stub
  167. }
  168. @Override
  169. public void mousePressed(MouseEvent e) {
  170. tempCps = null;
  171. dataSelected = null;
  172. edgeHighlight = null;
  173. // Object Selection
  174. for (CpsObject cps : model.getObjectsOnCanvas()) {
  175. cx = cps.getPosition().x;
  176. cy = cps.getPosition().y;
  177. if (x - controller.getScale() <= cx && y - controller.getScale() <= cy && x >= cx && y >= cy) {
  178. tempCps = cps;
  179. // If drawing an Edge (CTRL down)
  180. if (e.isControlDown()) {
  181. drawEdge = true;
  182. drawEdge = true;
  183. }
  184. if (tempCps.getClass() == HolonObject.class) {
  185. HolonObject tempObj = ((HolonObject) tempCps);
  186. dataSelected = tempObj.getElements();
  187. }
  188. }
  189. }
  190. // Edge Selection
  191. if (tempCps == null) {
  192. edgeHighlight = mousePositionOnEdge(x, y);
  193. }
  194. // Object Selection Highlighting (selectRect)
  195. objectSelectionHighlighting();
  196. repaint();
  197. }
  198. @Override
  199. public void mouseReleased(MouseEvent e) {
  200. if (drawEdge) {
  201. drawEdge = false;
  202. drawDeleteEdge();
  203. }
  204. // if Dragged reposition the Object
  205. if (dragging) {
  206. x = e.getX();
  207. y = e.getY();
  208. dragging = false;
  209. tempCps.setPosition(e.getX() - controller.getScaleDiv2(), e.getY() - controller.getScaleDiv2());
  210. }
  211. // Rightclick List
  212. if (e.getButton() == MouseEvent.BUTTON3) {
  213. if (e.getButton() == MouseEvent.BUTTON3 && tempCps != null) {
  214. itemDelete.setEnabled(true);
  215. } else {
  216. itemDelete.setEnabled(false);
  217. }
  218. popmenu.show(e.getComponent(), e.getX(), e.getY());
  219. }
  220. repaint();
  221. }
  222. @Override
  223. public void mouseDragged(MouseEvent e) {
  224. // If Edge is drawn
  225. if (drawEdge) {
  226. x = e.getX();
  227. y = e.getY();
  228. repaint();
  229. } else {
  230. try {
  231. // Au�erhalb des Randes gedragged?
  232. x = e.getX() - controller.getScaleDiv2();
  233. y = e.getY() - controller.getScaleDiv2();
  234. if (e.getX() < controller.getScaleDiv2())
  235. x = 0;
  236. else if (e.getX() > this.getWidth() - controller.getScaleDiv2())
  237. x = this.getWidth() - controller.getScale();
  238. if (e.getY() < controller.getScaleDiv2())
  239. y = 0;
  240. else if (e.getY() > this.getHeight() - controller.getScaleDiv2())
  241. y = this.getHeight() - controller.getScale();
  242. // Drag Position
  243. tempCps.setPosition(x, y);
  244. // Highlighting Position
  245. selectRect.setLocation(x - (controller.getScale() / 20), y - (controller.getScale() / 20));
  246. // TipText Position and name
  247. objectTT.setTipText(tempCps.getName());
  248. objectTT.setLocation(x, y + controller.getScale());
  249. repaint();
  250. } catch (Exception e2) {
  251. }
  252. }
  253. }
  254. @Override
  255. public void mouseMoved(MouseEvent e) {
  256. x = e.getX();
  257. y = e.getY();
  258. // Everytghing for the tooltip :)
  259. boolean on = false;
  260. for (CpsObject cps : model.getObjectsOnCanvas()) {
  261. cx = cps.getPosition().x;
  262. cy = cps.getPosition().y;
  263. if (x - controller.getScale() <= cx && y - controller.getScale() <= cy && x >= cx && y >= cy) {
  264. objectTT.setTipText(cps.getName());
  265. objectTT.setLocation(cx, cy + controller.getScale());
  266. on = true;
  267. }
  268. }
  269. if (!on) {
  270. objectTT.setLocation(-200, -200);
  271. objectTT.setTipText("");
  272. }
  273. }
  274. /**
  275. * Sets the Highlighting of the Selected Object
  276. */
  277. public void objectSelectionHighlighting() {
  278. if (tempCps != null) {
  279. selectRect.setBounds(tempCps.getPosition().x - (controller.getScale() / 20),
  280. tempCps.getPosition().y - (controller.getScale() / 20),
  281. controller.getScale() + controller.getScale() / 10,
  282. controller.getScale() + controller.getScale() / 10);
  283. controller.setSelectedObjectID(tempCps.getID());
  284. } else {
  285. controller.setSelectedObjectID(0);
  286. selectRect.setRect(0, 0, 0, 0);
  287. }
  288. }
  289. /**
  290. * Draws or Deletes an Edge
  291. */
  292. private void drawDeleteEdge() {
  293. boolean node = true;
  294. boolean newEdge = true;
  295. boolean onEdge = true;
  296. boolean deleteNode = false;
  297. CpsEdge e = null;
  298. CpsObject tempCPS = null;
  299. for (CpsObject cps : model.getObjectsOnCanvas()) {
  300. cx = cps.getPosition().x;
  301. cy = cps.getPosition().y;
  302. if (x - controller.getScale() <= cx && y - controller.getScale() <= cy && x >= cx && y >= cy
  303. && cps != tempCps) {
  304. node = false;
  305. onEdge = false;
  306. for (CpsEdge p : tempCps.getConnections()) {
  307. if ((p.getA() == tempCps && p.getB() == cps) || (p.getB() == tempCps && p.getA() == cps)) {
  308. newEdge = false;
  309. e = p;
  310. }
  311. }
  312. if (!newEdge) {
  313. controller.removeEdgesOnCanvas(e);
  314. tempCps.getConnections().remove(e);
  315. cps.getConnections().remove(e);
  316. // Node ohne Edge?
  317. if (e.getA().getClass() == CpsNode.class && e.getA().getConnections().isEmpty()) {
  318. tempCps = e.getA();
  319. deleteNode = true;
  320. }
  321. if (e.getB().getClass() == CpsNode.class && e.getB().getConnections().isEmpty()) {
  322. tempCPS = e.getB();
  323. deleteNode = true;
  324. }
  325. }
  326. if (newEdge) {
  327. e = new CpsEdge(cps, tempCps);
  328. cps.AddConnection(e);
  329. tempCps.AddConnection(e);
  330. controller.AddEdgeOnCanvas(e);
  331. }
  332. }
  333. }
  334. // Auf eine Edge gezoggen?
  335. if (onEdge) {
  336. CpsEdge p = mousePositionOnEdge(x, y);
  337. if (p != null) {
  338. CpsEdge temp = null;
  339. CpsEdge e1 = null;
  340. CpsEdge e2 = null;
  341. node = false;
  342. CpsNode n = new CpsNode("Node");
  343. n.setPosition(x - model.getScaleDiv2(), y - model.getScaleDiv2());
  344. controller.addObjectCanvas(n);
  345. CpsObject r, k;
  346. r = p.getA();
  347. k = p.getB();
  348. e = new CpsEdge(n, tempCps);
  349. n.AddConnection(e);
  350. tempCps.AddConnection(e);
  351. e1 = new CpsEdge(n, r);
  352. n.AddConnection(e1);
  353. r.AddConnection(e1);
  354. e2 = new CpsEdge(n, k);
  355. n.AddConnection(e2);
  356. k.AddConnection(e2);
  357. p.getA().getConnections().remove(p);
  358. p.getB().getConnections().remove(p);
  359. temp = p;
  360. controller.removeEdgesOnCanvas(temp);
  361. controller.AddEdgeOnCanvas(e);
  362. controller.AddEdgeOnCanvas(e1);
  363. controller.AddEdgeOnCanvas(e2);
  364. }
  365. }
  366. // ins leere Gedragged
  367. if (node) {
  368. CpsNode n = new CpsNode("Node");
  369. n.setPosition(x - model.getScaleDiv2(), y - model.getScaleDiv2());
  370. controller.addObjectCanvas(n);
  371. e = new CpsEdge(n, tempCps);
  372. n.AddConnection(e);
  373. tempCps.AddConnection(e);
  374. controller.AddEdgeOnCanvas(e);
  375. System.out.println("node ID: " + n.getID());
  376. }
  377. // Wenn ein Node ohne Connections da ist
  378. if (deleteNode) {
  379. controller.deleteObjectOnCanvas(tempCps);
  380. controller.deleteObjectOnCanvas(tempCPS);
  381. tempCPS = null;
  382. tempCps = null;
  383. objectSelectionHighlighting();
  384. }
  385. }
  386. /**
  387. * Checks if the mouse is on an Edge
  388. *
  389. * @param x
  390. * Position of the Mouse
  391. * @param y
  392. * Position of the Mouse
  393. *
  394. * @return CpsEdge the Mouse is on, null if the mouse is not on an Edge
  395. */
  396. public CpsEdge mousePositionOnEdge(int x, int y) {
  397. int lx, ly, hx, hy;
  398. for (CpsEdge p : model.getEdgesOnCanvas()) {
  399. Line2D l = new Line2D.Float(p.getA().getPosition().x, p.getA().getPosition().y, p.getB().getPosition().x,
  400. p.getB().getPosition().y);
  401. if (p.getA().getPosition().x > p.getB().getPosition().x) {
  402. hx = p.getA().getPosition().x + model.getScaleDiv2() + 7;
  403. lx = p.getB().getPosition().x + model.getScaleDiv2() - 7;
  404. } else {
  405. lx = p.getA().getPosition().x + model.getScaleDiv2() - 7;
  406. hx = p.getB().getPosition().x + model.getScaleDiv2() + 7;
  407. }
  408. if (p.getA().getPosition().y > p.getB().getPosition().y) {
  409. hy = p.getA().getPosition().y + model.getScaleDiv2() + 7;
  410. ly = p.getB().getPosition().y + model.getScaleDiv2() - 7;
  411. } else {
  412. ly = p.getA().getPosition().y + model.getScaleDiv2() - 7;
  413. hy = p.getB().getPosition().y + model.getScaleDiv2() + 7;
  414. }
  415. // distance from a point to a line and between both Objects
  416. if (l.ptLineDistSq(x - model.getScaleDiv2(), y - model.getScaleDiv2()) < 14 && x > lx && x < hx && y > ly
  417. && y < hy) {
  418. return p;
  419. }
  420. }
  421. return null;
  422. }
  423. /**
  424. * Checks if a double click was made
  425. *
  426. * @return true if doublecklick, false if not
  427. */
  428. private boolean doubleClick() {
  429. if (click) {
  430. click = false;
  431. return true;
  432. } else {
  433. click = true;
  434. Timer t = new Timer("doubleclickTimer", false);
  435. t.schedule(new TimerTask() {
  436. @Override
  437. public void run() {
  438. click = false;
  439. }
  440. }, 500);
  441. }
  442. return false;
  443. }
  444. }