Canvas.java 33 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033
  1. package ui.view.canvas;
  2. import java.awt.BasicStroke;
  3. import java.awt.Color;
  4. import java.awt.Font;
  5. import java.awt.Graphics;
  6. import java.awt.Graphics2D;
  7. import java.awt.RenderingHints;
  8. import java.awt.datatransfer.UnsupportedFlavorException;
  9. import java.awt.event.MouseEvent;
  10. import java.awt.event.MouseListener;
  11. import java.awt.event.MouseMotionListener;
  12. import java.awt.geom.Line2D;
  13. import java.awt.image.BufferedImage;
  14. import java.io.IOException;
  15. import java.util.ArrayList;
  16. import java.util.HashSet;
  17. import javax.swing.ImageIcon;
  18. import javax.swing.JFrame;
  19. import javax.swing.JLabel;
  20. import javax.swing.JOptionPane;
  21. import javax.swing.JScrollPane;
  22. import javax.swing.JTabbedPane;
  23. import javax.swing.SwingUtilities;
  24. import com.google.gson.JsonParseException;
  25. import model.AbstractCanvasObject;
  26. import model.Edge;
  27. import model.GroupNode;
  28. import model.HolonObject;
  29. import model.HolonSwitch;
  30. import model.Node;
  31. import preferences.ColorPreference;
  32. import ui.controller.Control;
  33. import ui.model.Consumer;
  34. import ui.model.DecoratedCable;
  35. import ui.model.DecoratedGroupNode;
  36. import ui.model.DecoratedHolonObject;
  37. import ui.model.DecoratedHolonObject.HolonObjectState;
  38. import ui.model.DecoratedSwitch;
  39. import ui.model.ExitCable;
  40. import ui.model.DecoratedSwitch.SwitchState;
  41. import ui.view.inspector.UnitGraph;
  42. import ui.model.Model;
  43. import ui.model.Passiv;
  44. import ui.model.Supplier;
  45. import ui.model.VisualRepresentationalState;
  46. import utility.ImageImport;
  47. import utility.Vector2Int;
  48. /**
  49. * This Class is the Canvas. All Objects will be visualized here
  50. *
  51. * @author Gruppe14
  52. */
  53. public class Canvas extends AbstractCanvas implements MouseListener, MouseMotionListener {
  54. private static final long serialVersionUID = 1L;
  55. public boolean disabled = false;
  56. GroupNode groupNode = null;
  57. private static Color[] colors = { ColorPreference.HolonObject.Producer, ColorPreference.HolonObject.NotSupplied,
  58. ColorPreference.HolonObject.PartiallySupplied, ColorPreference.HolonObject.Supplied,
  59. ColorPreference.HolonObject.OverSupplied, ColorPreference.HolonObject.NoEnergy };
  60. /**
  61. * Constructor.
  62. *
  63. * @param mod the Model
  64. * @param control the Controller
  65. * @param unitGraph
  66. */
  67. public Canvas(Model mod, Control control, UnitGraph unitGraph) {
  68. toolTip = false;
  69. this.controller = control;
  70. this.model = mod;
  71. scalediv20 = model.getScale() / 20;
  72. showConnectionInformation = true;
  73. control.setMaxCapacity(10000);
  74. popmenu.add(itemCut);
  75. popmenu.add(itemCopy);
  76. popmenu.add(itemPaste);
  77. popmenu.add(itemDelete);
  78. popmenu.add(itemAlign);
  79. popmenu.addSeparator();
  80. popmenu.add(itemGroup);
  81. popmenu.add(itemUngroup);
  82. popmenu.add(itemCreateTemplate);
  83. itemDelete.setEnabled(false);
  84. itemCut.setEnabled(false);
  85. itemCopy.setEnabled(false);
  86. itemPaste.setEnabled(true);
  87. itemAlign.setEnabled(false);
  88. itemGroup.setEnabled(false);
  89. itemUngroup.setEnabled(false);
  90. itemCut.setText("Cut");
  91. itemGroup.addActionListener(actionEvent -> {
  92. // calculate uppernode pos (taken from the controller)
  93. unPos = new Vector2Int(0, 0);
  94. animCps = new ArrayList<>();
  95. for (AbstractCanvasObject cps : model.getSelectedObjects()) {
  96. animCps.add(cps); // add to animation Cps ArrayList
  97. unPos = unPos.add(cps.getPosition());
  98. }
  99. unPos = unPos.divide(animCps.size());
  100. // save old Position
  101. savePos = new ArrayList<>();
  102. for (int i = 0; i < animCps.size(); i++) {
  103. savePos.add(animCps.get(i).getPosition().clone());
  104. }
  105. animT = new javax.swing.Timer(animDelay, actionEvent1 -> {
  106. if (animDuration - animDelay > 0 && animCps.size() > 1) {
  107. for (AbstractCanvasObject animCpObject : animCps) {
  108. Vector2Int pos = animCpObject.getPosition();
  109. Vector2Int difference = pos.subtract(unPos);
  110. Vector2Int result = pos.subtract(difference.divide(animSteps));
  111. pos.set(result);
  112. }
  113. repaint();
  114. animDuration -= animDelay;
  115. animSteps--;
  116. } else {
  117. animDuration = ANIMTIME;
  118. animSteps = animDuration / animDelay;
  119. animT.stop();
  120. for (int i = 0; i < animCps.size(); i++) {
  121. animCps.get(i).getPosition().set(savePos.get(i));
  122. }
  123. controller.addUpperNode("GroupNode", groupNode, animCps);
  124. controller.calculateStateAndVisualForCurrentTimeStep();
  125. controller.clearSelection();
  126. repaint();
  127. }
  128. });
  129. animT.start();
  130. });
  131. itemUngroup.addActionListener(actionEvent -> {
  132. // save old Position
  133. int upperNodeId = tempCps.getId();
  134. closeUpperNodeTab(upperNodeId);
  135. savePos = new ArrayList<>();
  136. animCps = ((GroupNode) tempCps).getNodes();
  137. controller.ungroupGroupNode((GroupNode) tempCps, groupNode);
  138. for (int i = 0; i < animCps.size(); i++) {
  139. savePos.add(animCps.get(i).getPosition().clone());
  140. }
  141. for (AbstractCanvasObject cps : animCps) {
  142. int x = tempCps.getPosition().getX();
  143. int y = tempCps.getPosition().getY();
  144. cps.setPosition(new Vector2Int(x, y));
  145. }
  146. animT = new javax.swing.Timer(animDelay, actionEvent1 -> {
  147. controller.clearSelection();
  148. if (animDuration - animDelay >= 0) {
  149. for (int i = 0; i < animCps.size(); i++) {
  150. Vector2Int pos = animCps.get(i).getPosition();
  151. Vector2Int difference = pos.subtract(savePos.get(i));
  152. Vector2Int result = pos.subtract(difference.divide(animSteps));
  153. pos.set(result);
  154. }
  155. repaint();
  156. animDuration -= animDelay;
  157. animSteps--;
  158. } else {
  159. animDuration = ANIMTIME;
  160. animSteps = animDuration / animDelay;
  161. animT.stop();
  162. for (int i = 0; i < animCps.size(); i++) {
  163. animCps.get(i).getPosition().set(savePos.get(i));
  164. }
  165. controller.calculateStateAndVisualForCurrentTimeStep();
  166. repaint();
  167. }
  168. });
  169. animT.start();
  170. });
  171. // adds the selected object(s) to the statistic panel
  172. itemDelete.addActionListener(actionEvent -> {
  173. // Remove the selected Object objects
  174. // Edge Deleting
  175. if (tempCps == null && edgeHighlight != null) {
  176. controller.removeEdgesOnCanvas(edgeHighlight);
  177. // Look for a CPSNode with no Connections and delete them
  178. if (edgeHighlight.getA() instanceof Node
  179. && edgeHighlight.getA().getConnections().size() == 0) {
  180. controller.delCanvasObject(edgeHighlight.getA(), false);
  181. }
  182. if (edgeHighlight.getB() instanceof Node
  183. && edgeHighlight.getB().getConnections().size() == 0) { // Look on the other end of the cable
  184. controller.delCanvasObject(edgeHighlight.getB(), false);
  185. }
  186. edgeHighlight = null;
  187. }
  188. for (AbstractCanvasObject cps : model.getSelectedObjects()) {
  189. controller.delCanvasObject(cps, false);
  190. toolTip = false;
  191. }
  192. controller.tryAutoSave();
  193. controller.clearSelection();
  194. tempCps = null;
  195. repaint();
  196. });
  197. itemCut.addActionListener(actionEvent -> {
  198. controller.cut(null);
  199. itemPaste.setEnabled(true);
  200. repaint();
  201. });
  202. itemCopy.addActionListener(actionEvent -> {
  203. if (tempCps instanceof GroupNode)
  204. controller.getObjectsInDepth();
  205. controller.copy(null);
  206. itemPaste.setEnabled(true);
  207. repaint();
  208. });
  209. itemAlign.addActionListener(actionEvent -> {
  210. for (AbstractCanvasObject cps : model.getSelectedObjects())
  211. align(cps, Model.getScaleDiv2());
  212. repaint();
  213. });
  214. itemPaste.addActionListener(actionEvent -> {
  215. try {
  216. controller.paste(null, mousePosition);
  217. } catch (JsonParseException | UnsupportedFlavorException | IOException e1) {
  218. JLabel message = new JLabel("The Clipboard information cannot be pastet into Application.");
  219. JOptionPane.showMessageDialog(null, message, "", JOptionPane.ERROR_MESSAGE);
  220. }
  221. repaint();
  222. });
  223. /*
  224. * create Template
  225. */
  226. itemCreateTemplate.addActionListener(actionEvent -> {
  227. controller.createTemplate((HolonObject) tempCps, (JFrame) SwingUtilities.getRoot(this));
  228. });
  229. this.addMouseListener(this);
  230. this.addMouseMotionListener(this);
  231. }
  232. /**
  233. * Paints all Components on the Canvas.
  234. *
  235. * @param g Graphics
  236. */
  237. protected void paintCanvasObject(Graphics2D g, DecoratedHolonObject decoratedHolonObject) {
  238. Vector2Int pos = decoratedHolonObject.getModel().getPosition();
  239. Color statecolor = ColorPreference.HolonObject.getStateColor(decoratedHolonObject.getState());
  240. g.setColor(statecolor);
  241. g.fillRect(pos.getX() - controller.getScaleDiv2(), pos.getY() - controller.getScaleDiv2(),
  242. controller.getScale(), controller.getScale());
  243. drawCanvasObject(g, decoratedHolonObject.getModel().getImage(), pos);
  244. }
  245. protected void drawCanvasObjectString(Graphics2D g, Vector2Int posOfCanvasObject, float energy) {
  246. g.setColor(Color.BLACK);
  247. g.setFont(new Font("TimesNewRoman", Font.PLAIN, (int) (controller.getScale() / 4f)));
  248. g.drawString((energy > 0) ? "+" + Float.toString(energy) : Float.toString(energy),
  249. posOfCanvasObject.getX() - controller.getScaleDiv2(),
  250. posOfCanvasObject.getY() - controller.getScaleDiv2() - 1);
  251. }
  252. protected void paintConsumer(Graphics2D g, Consumer con) {
  253. paintCanvasObject(g, con);
  254. drawCanvasObjectString(g, con.getModel().getPosition(), -con.getEnergyNeededFromNetwork());
  255. if (model.getShowSupplyBars()) {
  256. paintSupplyBar(g, con.getSupplyBarPercentage(), ColorPreference.HolonObject.getStateColor(con.getState()),
  257. con.getModel().getPosition());
  258. }
  259. }
  260. protected void paintSupplier(Graphics2D g, Supplier sup) {
  261. paintCanvasObject(g, sup);
  262. drawCanvasObjectString(g, sup.getModel().getPosition(), sup.getEnergyToSupplyNetwork());
  263. }
  264. protected void drawCanvasObject(Graphics2D g, String Image, Vector2Int pos) {
  265. g.drawImage(ImageImport.loadImage(Image, controller.getScale(), controller.getScale()),
  266. pos.getX() - controller.getScaleDiv2(), pos.getY() - controller.getScaleDiv2(), controller.getScale(),
  267. controller.getScale(), null);
  268. }
  269. protected void paintCable(Graphics2D g, DecoratedCable cable, boolean isSelected) {
  270. Vector2Int start = cable.getModel().getA().getPosition();
  271. Vector2Int end = cable.getModel().getB().getPosition();
  272. float currentEnergy = cable.getFlowEnergy();
  273. float capacity = cable.getModel().maxCapacity;
  274. boolean unlimited = cable.getModel().isUnlimitedCapacity();
  275. switch (cable.getState()) {
  276. case Burned:
  277. g.setColor(ColorPreference.Edge.Burned);
  278. g.setStroke(new BasicStroke(2));
  279. break;
  280. case Working:
  281. g.setColor(ColorPreference.Edge.Working);
  282. g.setStroke(new BasicStroke(unlimited ? 2f : (currentEnergy / capacity * 2f) + 1));
  283. break;
  284. }
  285. if (isSelected) {
  286. g.setColor(Color.lightGray);
  287. }
  288. g.drawLine(start.getX(), start.getY(), end.getX(), end.getY());
  289. if (showConnectionInformation) {
  290. Vector2Int middle = new Vector2Int((start.getX() + end.getX()) / 2, (start.getY() + end.getY()) / 2);
  291. g.setFont(new Font("TimesRoman", Font.PLAIN, Math.max((int) (controller.getScale() / 3.5f), 10)));
  292. g.drawString(currentEnergy + "/" + (unlimited ? "\u221E" : capacity), middle.getX(), middle.getY());
  293. }
  294. }
  295. protected void paintSwitch(Graphics2D g, DecoratedSwitch dSwitch) {
  296. drawCanvasObject(g, dSwitch.getState() == SwitchState.Open ? HolonSwitch.getSwitchOpenImage()
  297. : HolonSwitch.getSwitchClosedImage(), dSwitch.getModel().getPosition());
  298. }
  299. protected void paintExitCable(Graphics2D g, ExitCable eCable) {
  300. Vector2Int start = eCable.getStart().getPosition();
  301. Vector2Int end = eCable.getFinish().getPosition();
  302. float currentEnergy = eCable.getCable().getFlowEnergy();
  303. float capacity = eCable.getCable().getModel().maxCapacity;
  304. boolean unlimited = eCable.getCable().getModel().isUnlimitedCapacity();
  305. switch (eCable.getCable().getState()) {
  306. case Burned:
  307. g.setColor(Color.RED);
  308. g.setStroke(new BasicStroke(2));
  309. break;
  310. case Working:
  311. g.setColor(new Color(13, 175, 28));
  312. g.setStroke(new BasicStroke(unlimited ? 2f : (currentEnergy / capacity * 2f) + 1));
  313. break;
  314. }
  315. g.drawLine(start.getX(), start.getY(), end.getX(), end.getY());
  316. Vector2Int middle = new Vector2Int((start.getX() + end.getX()) / 2, (start.getY() + end.getY()) / 2);
  317. g.setFont(new Font("TimesRoman", Font.PLAIN, Math.max((int) (controller.getScale() / 3.5f), 10)));
  318. g.drawString(currentEnergy + "/" + (unlimited ? "\u221E" : capacity), middle.getX(), middle.getY());
  319. }
  320. protected void paintGroupNode(Graphics2D g, DecoratedGroupNode dGroupNode) {
  321. Vector2Int pos = dGroupNode.getModel().getPosition();
  322. g.setColor(Color.lightGray);
  323. g.fillRect(pos.getX() - controller.getScaleDiv2(), pos.getY() - controller.getScaleDiv2(),
  324. controller.getScale(), controller.getScale());
  325. drawCanvasObject(g, "/Images/upper_node.png", pos);
  326. paintGroupNodeBar(g, dGroupNode, pos);
  327. }
  328. private void paintGroupNodeBar(Graphics2D g, DecoratedGroupNode dGroupNode, Vector2Int pos) {
  329. // +1, -2, -1 little Adjustment for pixel perfect alignment
  330. int barWidth = (int) (controller.getScale());
  331. int barHeight = (int) (controller.getScale() / 5);
  332. g.setColor(Color.WHITE);
  333. g.fillRect(pos.getX() - controller.getScaleDiv2(), pos.getY() + controller.getScaleDiv2() - 1, (int) barWidth,
  334. barHeight);
  335. float[] percentages = getGroupNodeBarPercentages(dGroupNode);
  336. for (int i = 5; i >= 0; i--) {
  337. g.setColor(colors[i]);
  338. g.fillRect(pos.getX() - controller.getScaleDiv2(), pos.getY() + controller.getScaleDiv2() - 1,
  339. (int) (barWidth * percentages[i] - 1), barHeight);
  340. }
  341. // g.setColor(color);
  342. // g.fillRect(pos.getX() - controller.getScaleDiv2(), pos.getY() + controller.getScaleDiv2() - 1, (int) (barWidth * (percentage < 1 ? percentage : 1.0f) - 1), barHeight);
  343. g.setColor(Color.BLACK);
  344. g.setStroke(new BasicStroke(1));
  345. g.drawRect(pos.getX() - controller.getScaleDiv2(), pos.getY() + controller.getScaleDiv2() - 1, barWidth - 1,
  346. barHeight);
  347. }
  348. /**
  349. * HardCoded Stuff dont try at Home ;)
  350. *
  351. * @param dGroupNode
  352. * @return
  353. */
  354. public float[] getGroupNodeBarPercentages(DecoratedGroupNode dGroupNode) {
  355. int[] amountOfObjects = new int[6];
  356. amountOfObjects[0] = dGroupNode.getAmountOfSupplier();
  357. amountOfObjects[1] = dGroupNode.getAmountOfConsumerWithState(HolonObjectState.NOT_SUPPLIED);
  358. amountOfObjects[2] = dGroupNode.getAmountOfConsumerWithState(HolonObjectState.PARTIALLY_SUPPLIED);
  359. amountOfObjects[3] = dGroupNode.getAmountOfConsumerWithState(HolonObjectState.SUPPLIED);
  360. amountOfObjects[4] = dGroupNode.getAmountOfConsumerWithState(HolonObjectState.OVER_SUPPLIED);
  361. amountOfObjects[5] = dGroupNode.getAmountOfPassiv();
  362. int countHolonObjects = amountOfObjects[0] + amountOfObjects[1] + amountOfObjects[2] + amountOfObjects[3]
  363. + amountOfObjects[4] + amountOfObjects[5];
  364. float[] percentages = new float[6];
  365. int count = 0;
  366. for (int i = 0; i < 6; i++) {
  367. count += amountOfObjects[i];
  368. percentages[i] = (float) count / (float) countHolonObjects;
  369. }
  370. return percentages;
  371. }
  372. private void paintSupplyBar(Graphics2D g, float percentage, Color color, Vector2Int pos) {
  373. // +1, -2, -1 little Adjustment for pixel perfect alignment
  374. int barWidth = (int) (controller.getScale());
  375. int barHeight = (int) (controller.getScale() / 5);
  376. g.setColor(Color.WHITE);
  377. g.fillRect(pos.getX() - controller.getScaleDiv2(), pos.getY() + controller.getScaleDiv2() - 1, (int) barWidth,
  378. barHeight);
  379. g.setColor(color);
  380. g.fillRect(pos.getX() - controller.getScaleDiv2(), pos.getY() + controller.getScaleDiv2() - 1,
  381. (int) (barWidth * (percentage < 1 ? percentage : 1.0f) - 1), barHeight);
  382. g.setColor(Color.BLACK);
  383. g.setStroke(new BasicStroke(1));
  384. g.drawRect(pos.getX() - controller.getScaleDiv2(), pos.getY() + controller.getScaleDiv2() - 1, barWidth - 1,
  385. barHeight);
  386. g.setFont(new Font("TimesNewRoman", Font.PLAIN, (int) (barHeight * 1.5) - 2));
  387. String percentageString = (Math.round((percentage * 100))) + "%";
  388. int stringWidth = (int) g.getFontMetrics().getStringBounds(percentageString, g).getWidth();
  389. if (percentage > 1.0f)
  390. g.setColor(Color.WHITE); // Just to see better on purple
  391. g.drawString(percentageString, pos.getX() + 1 - stringWidth / 2,
  392. pos.getY() + controller.getScaleDiv2() - 1 + barHeight);
  393. }
  394. // old code
  395. void drawMarker(Graphics2D g) {
  396. Color transparentGrey = ColorPreference.Panel.ObjectSelection;
  397. if (sx > x && sy > y) {
  398. g.drawRect(x, y, sx - x, sy - y);
  399. g.setColor(transparentGrey);
  400. g.fillRect(x, y, sx - x, sy - y);
  401. } else if (sx < x && sy < y) {
  402. g.drawRect(sx, sy, x - sx, y - sy);
  403. g.setColor(transparentGrey);
  404. g.fillRect(sx, sy, x - sx, y - sy);
  405. } else if (sx >= x) {
  406. g.drawRect(x, sy, sx - x, y - sy);
  407. g.setColor(transparentGrey);
  408. g.fillRect(x, sy, sx - x, y - sy);
  409. } else if (sy >= y) {
  410. g.drawRect(sx, y, x - sx, sy - y);
  411. g.setColor(transparentGrey);
  412. g.fillRect(sx, y, x - sx, sy - y);
  413. }
  414. }
  415. public void paintComponent(Graphics g) {
  416. super.paintComponent(g);
  417. Graphics2D g2d = (Graphics2D) g;
  418. g2d.setRenderingHints(new RenderingHints(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON));
  419. // -->Old code TODO(Tom2021-12-1): remove
  420. if (drawEdge) {
  421. g2d.setColor(Color.BLACK);
  422. g2d.setStroke(new BasicStroke(1));
  423. g2d.drawLine(tempCps.getPosition().getX(), tempCps.getPosition().getY(), x, y);
  424. }
  425. // <--
  426. // SelectedCable
  427. HashSet<Edge> selectedEdges = new HashSet<Edge>();
  428. for (AbstractCanvasObject aCps : model.getSelectedObjects()) {
  429. for (Edge edge : aCps.getConnections()) {
  430. selectedEdges.add(edge);
  431. }
  432. }
  433. if (model.getSelectedEdge() != null)
  434. selectedEdges.add(model.getSelectedEdge());
  435. // timstep:
  436. g.setFont(new Font("TimesNewRoman", Font.PLAIN, Math.max((int) (controller.getScale() / 3.5f), 10)));
  437. g2d.setColor(Color.BLACK);
  438. VisualRepresentationalState visualState = controller.getSimManager().getActualVisualRepresentationalState();
  439. // VisualState Representation:
  440. if (visualState == null) {
  441. System.out.println("AHHH");
  442. return;
  443. }
  444. for (ExitCable cable : visualState.getExitCableList()) {
  445. paintExitCable(g2d, cable);
  446. }
  447. for (DecoratedCable cable : visualState.getCableList()) {
  448. paintCable(g2d, cable, selectedEdges.contains(cable.getModel()));
  449. }
  450. for (DecoratedGroupNode dGroupNode : visualState.getGroupNodeList()) {
  451. paintGroupNode(g2d, dGroupNode);
  452. }
  453. for (Consumer con : visualState.getConsumerList()) {
  454. paintConsumer(g2d, con);
  455. }
  456. for (Supplier sup : visualState.getSupplierList()) {
  457. paintSupplier(g2d, sup);
  458. }
  459. for (Passiv pas : visualState.getPassivList()) {
  460. paintCanvasObject(g2d, pas);
  461. }
  462. for (DecoratedSwitch dSwitch : visualState.getSwitchList()) {
  463. paintSwitch(g2d, dSwitch);
  464. }
  465. for (Node node : visualState.getNodeList()) {
  466. drawCanvasObject(g2d, "/Images/node.png", node.getPosition());
  467. }
  468. // -->oldCode
  469. if (doMark) {
  470. g2d.setColor(Color.BLACK);
  471. g2d.setStroke(new BasicStroke(0));
  472. drawMarker(g2d);
  473. }
  474. // Test Selection
  475. // Objects:
  476. g2d.setColor(Color.BLUE);
  477. g2d.setStroke(new BasicStroke(1));
  478. Color transparentGrey = ColorPreference.Panel.ObjectSelection;
  479. for (AbstractCanvasObject aCps : model.getSelectedObjects()) {
  480. if (aCps instanceof Node) {
  481. Vector2Int pos = aCps.getPosition();
  482. g2d.setColor(transparentGrey);
  483. g2d.fillOval(pos.getX() - (int) (controller.getScaleDiv2()),
  484. pos.getY() - (int) (controller.getScaleDiv2()), controller.getScale(), controller.getScale());
  485. g2d.setColor(Color.LIGHT_GRAY);
  486. g2d.setStroke(new BasicStroke(2));
  487. g2d.drawOval(pos.getX() - (int) (controller.getScaleDiv2()),
  488. pos.getY() - (int) (controller.getScaleDiv2()), controller.getScale(), controller.getScale());
  489. } else {
  490. Vector2Int pos = aCps.getPosition();
  491. g2d.setColor(transparentGrey);
  492. g2d.fillRect(pos.getX() - (int) (controller.getScaleDiv2() * 1.5f),
  493. pos.getY() - (int) (controller.getScaleDiv2() * 1.5f), (int) (controller.getScale() * 1.5f),
  494. (int) (controller.getScale() * 1.5f));
  495. g2d.setColor(Color.LIGHT_GRAY);
  496. g2d.setStroke(new BasicStroke(2));
  497. g2d.drawRect(pos.getX() - (int) (controller.getScaleDiv2() * 1.5f),
  498. pos.getY() - (int) (controller.getScaleDiv2() * 1.5f), (int) (controller.getScale() * 1.5f),
  499. (int) (controller.getScale() * 1.5f));
  500. }
  501. }
  502. // maybeReplace:
  503. if (mayBeReplaced != null) {
  504. g2d.setColor(Color.RED);
  505. Vector2Int pos = mayBeReplaced.getPosition();
  506. g2d.drawImage(ImageImport.loadImage("/Images/replace.png"), pos.getX() + controller.getScaleDiv2(),
  507. pos.getY() - controller.getScale(), controller.getScaleDiv2(), controller.getScaleDiv2(), null);
  508. }
  509. // <-- OldCode
  510. }
  511. @Override
  512. public void mouseClicked(MouseEvent e) {
  513. }
  514. @Override
  515. public void mouseEntered(MouseEvent e) {
  516. }
  517. @Override
  518. public void mouseExited(MouseEvent e) {
  519. }
  520. @Override
  521. public void mousePressed(MouseEvent e) {
  522. this.grabFocus();
  523. if (!disabled) {
  524. tempCps = null;
  525. edgeHighlight = null;
  526. controller.setSelecteEdge(null);
  527. // Object Selection
  528. for (AbstractCanvasObject cps : model.getObjectsOnCanvas()) {
  529. cx = cps.getPosition().getX() - controller.getScaleDiv2();
  530. cy = cps.getPosition().getY() - controller.getScaleDiv2();
  531. if (x - controller.getScale() <= cx && y - controller.getScale() <= cy && x >= cx && y >= cy) {
  532. tempCps = cps;
  533. dragging = true;
  534. if (e.isControlDown() && tempCps != null) {
  535. System.out.println("Add Remove Selection CANVAS");
  536. if (model.getSelectedObjects().contains(tempCps)) {
  537. controller.removeObjectFromSelection(tempCps);
  538. } else {
  539. controller.addSelectedObject(tempCps);
  540. }
  541. }
  542. // If drawing an Edge (CTRL down)
  543. if (tempCps.getClass() == HolonObject.class) {
  544. HolonObject tempObj = ((HolonObject) tempCps);
  545. dataSelected = tempObj.getElements();
  546. }
  547. if (e.isShiftDown()) {
  548. drawEdge = true;
  549. dragging = false;
  550. }
  551. }
  552. }
  553. // Edge Selection
  554. if (tempCps == null) {
  555. edgeHighlight = mousePositionOnEdge(x, y);
  556. controller.setSelecteEdge(edgeHighlight);
  557. if (!e.isControlDown() && e.getButton() != MouseEvent.BUTTON3) {
  558. controller.clearSelection();
  559. }
  560. }
  561. if (edgeHighlight == null && tempCps == null) {
  562. sx = e.getX();
  563. sy = e.getY();
  564. doMark = true;
  565. }
  566. repaint();
  567. }
  568. }
  569. @Override
  570. public void mouseReleased(MouseEvent e) {
  571. if (!disabled) {
  572. x = e.getX();
  573. y = e.getY();
  574. dragging = false;
  575. if (drawEdge) {
  576. drawEdge = false;
  577. drawDeleteEdge();
  578. }
  579. if (dragged) {
  580. try {
  581. /**
  582. * Save before further Dragged interactions happen
  583. */
  584. controller.autoSave();
  585. } catch (IOException ex) {
  586. System.err.println("AutoSave error by dragging");
  587. ex.printStackTrace();
  588. }
  589. /**
  590. * check if a unique tempCps could replace an Object on the canvas
  591. */
  592. if (model.getSelectedObjects().size() == 1 && checkForReplacement(model.getObjectsOnCanvas(),
  593. tempCps, tempCps.getPosition().getX(), tempCps.getPosition().getY())) {
  594. /**
  595. * if UpperNode would be replaced, close its tabs
  596. */
  597. if (mayBeReplaced instanceof GroupNode)
  598. closeUpperNodeTab(mayBeReplaced.getId());
  599. /**
  600. * replace on canvas (will save)
  601. */
  602. controller.replaceCanvasObject(mayBeReplaced, tempCps);
  603. mayBeReplaced = null;
  604. }
  605. }
  606. if (!e.isControlDown() && !dragged && tempCps != null && MouseEvent.BUTTON3 != e.getButton()) {
  607. controller.clearSelection();
  608. controller.addSelectedObject(tempCps);
  609. if (tempCps instanceof GroupNode)
  610. controller.getObjectsInDepth();
  611. }
  612. dragged = false;
  613. // Rightclick List
  614. setRightClickMenu(e);
  615. markObjects();
  616. boolean doubleclick = doubleClick();
  617. if (doubleclick && tempCps instanceof HolonSwitch && MouseEvent.BUTTON3 != e.getButton()
  618. && tempCps != null) {
  619. ((HolonSwitch) tempCps).switchState();
  620. }
  621. if (doubleclick && tempCps != null && tempCps instanceof GroupNode) {
  622. controller.getGui().openNewUpperNodeTab((GroupNode) tempCps);
  623. }
  624. controller.calculateStateAndVisualForTimeStep(model.getActualTimeStep());
  625. repaint();
  626. }
  627. }
  628. @Override
  629. public void mouseDragged(MouseEvent e) {
  630. if (!disabled) {
  631. // If Edge is drawn
  632. x = e.getX();
  633. y = e.getY();
  634. if (!model.getSelectedObjects().contains(tempCps) && !doMark) {
  635. controller.clearSelection();
  636. if (tempCps != null) {
  637. controller.addSelectedObject(tempCps);
  638. }
  639. }
  640. if (dragging) {
  641. try {
  642. dragged = true;
  643. float xDist, yDist; // Distance
  644. x = e.getX();
  645. y = e.getY();
  646. // Make sure its in bounds
  647. int scaleDiv2 = controller.getScaleDiv2();
  648. if (e.getX() < scaleDiv2)
  649. x = scaleDiv2;
  650. else if (e.getX() > this.getWidth() - scaleDiv2)
  651. x = this.getWidth() - scaleDiv2;
  652. if (e.getY() < scaleDiv2)
  653. y = scaleDiv2;
  654. else if (e.getY() > this.getHeight() - scaleDiv2)
  655. y = this.getHeight() - scaleDiv2;
  656. // Distance
  657. xDist = x - tempCps.getPosition().getX();
  658. yDist = y - tempCps.getPosition().getY();
  659. tempCps.setPosition(x, y); // Drag Position
  660. // ToolTipText Position and name
  661. toolTip = true;
  662. toolTipText = tempCps.getName() + ", " + tempCps.getId();
  663. toolTipPos.setX(tempCps.getPosition().getX() - scaleDiv2);
  664. toolTipPos.setY(tempCps.getPosition().getY() + scaleDiv2);
  665. // All Selected Objects
  666. for (AbstractCanvasObject cps : model.getSelectedObjects()) {
  667. if (cps != tempCps) {
  668. x = (int) (cps.getPosition().getX() + xDist);
  669. y = (int) (cps.getPosition().getY() + yDist);
  670. // Make sure its in bounds
  671. if (x <= scaleDiv2)
  672. x = scaleDiv2;
  673. else if (x > this.getWidth() - scaleDiv2)
  674. x = this.getWidth() - scaleDiv2;
  675. if (y <= scaleDiv2)
  676. y = scaleDiv2;
  677. else if (y > this.getHeight() - scaleDiv2)
  678. y = this.getHeight() - scaleDiv2;
  679. cps.setPosition(x, y);
  680. }
  681. }
  682. /**
  683. * check if something might be replaced
  684. */
  685. if (model.getSelectedObjects().size() == 1)
  686. checkForReplacement(model.getObjectsOnCanvas(), tempCps, x, y);
  687. repaint();
  688. } catch (Exception eex) {
  689. }
  690. }
  691. // Mark Objects
  692. if (doMark) {
  693. tempSelected.clear();
  694. for (AbstractCanvasObject cps : model.getObjectsOnCanvas()) {
  695. int x1 = sx, x2 = x, y1 = sy, y2 = y;
  696. if (sx >= x) {
  697. x1 = x;
  698. x2 = sx;
  699. }
  700. if (sy >= y) {
  701. y1 = y;
  702. y2 = sy;
  703. }
  704. if (x1 <= cps.getPosition().getX() + Model.getScaleDiv2()
  705. && y1 <= cps.getPosition().getY() + Model.getScaleDiv2() && x2 >= cps.getPosition().getX()
  706. && y2 >= cps.getPosition().getY()) {
  707. tempSelected.add(cps);
  708. }
  709. }
  710. }
  711. repaint();
  712. }
  713. }
  714. @Override
  715. public void mouseMoved(MouseEvent e) {
  716. if (!disabled) {
  717. x = e.getX();
  718. y = e.getY();
  719. // Everything for the tooltip :)
  720. boolean on = false;
  721. for (AbstractCanvasObject cps : model.getObjectsOnCanvas()) {
  722. cx = cps.getPosition().getX() - controller.getScaleDiv2();
  723. cy = cps.getPosition().getY() - controller.getScaleDiv2();
  724. on = setToolTipInfoAndPosition(on, cps);
  725. }
  726. if (on || (!on && toolTip))
  727. repaint();
  728. toolTip = on;
  729. }
  730. }
  731. /**
  732. * Draws or Deletes an Edge.
  733. */
  734. void drawDeleteEdge() {
  735. if (getMousePosition() != null) {
  736. boolean node = true;
  737. boolean newEdge = true;
  738. boolean onEdge = true;
  739. boolean deleteNode = false;
  740. Edge e = null;
  741. for (AbstractCanvasObject cps : model.getObjectsOnCanvas()) {
  742. cx = cps.getPosition().getX() - controller.getScaleDiv2();
  743. cy = cps.getPosition().getY() - controller.getScaleDiv2();
  744. if (x - controller.getScale() <= cx && y - controller.getScale() <= cy && x >= cx && y >= cy
  745. && cps != tempCps) {
  746. node = false;
  747. onEdge = false;
  748. for (Edge p : tempCps.getConnections()) {
  749. if ((p.getA() == tempCps && p.getB() == cps) || (p.getB() == tempCps && p.getA() == cps)) {
  750. newEdge = false;
  751. e = p;
  752. }
  753. }
  754. if (!newEdge) {
  755. controller.removeEdgesOnCanvas(e);
  756. // Node ohne Edge?
  757. if (e.getA().getClass() == Node.class && e.getA().getConnections().isEmpty()) {
  758. tempCps = e.getA();
  759. deleteNode = true;
  760. }
  761. if (e.getB().getClass() == Node.class && e.getB().getConnections().isEmpty()) {
  762. deleteNode = true;
  763. }
  764. } else {
  765. if (!(cps instanceof GroupNode || tempCps instanceof GroupNode)) {
  766. e = new Edge(cps, tempCps, model.getMaxCapacity());
  767. controller.addEdgeOnCanvas(e);
  768. } else if (cps instanceof GroupNode && !(tempCps instanceof GroupNode)) {
  769. GroupNode thisUpperNode = (GroupNode) cps;
  770. Object[] possibilities = thisUpperNode.getNodes().stream().map(aCps -> new ACpsHandle(aCps))
  771. .filter(aCpsHandle -> !(aCpsHandle.object instanceof GroupNode)).toArray();
  772. if (possibilities.length != 0) {
  773. ACpsHandle selected = (ACpsHandle) JOptionPane.showInputDialog(this,
  774. "Select a inside Object:", "Connection To?", JOptionPane.OK_OPTION,
  775. new ImageIcon(new BufferedImage(1, 1, BufferedImage.TYPE_INT_ARGB)),
  776. possibilities, "");
  777. if (selected != null) {
  778. e = new Edge(selected.object, tempCps, model.getMaxCapacity());
  779. controller.addEdgeOnCanvas(e);
  780. }
  781. } else {
  782. Node n = new Node("Node");
  783. n.setPosition(x, y);
  784. controller.addObjUpperNode(n, thisUpperNode);
  785. e = new Edge(n, tempCps, model.getMaxCapacity());
  786. controller.addEdgeOnCanvas(e);
  787. }
  788. }
  789. }
  790. }
  791. }
  792. // Edge auf eine Edge gezogen?
  793. if (onEdge && !checkForReplacement(x, y)) {
  794. Edge p = mousePositionOnEdge(x, y);
  795. if (p != null) {
  796. Edge e1;
  797. Edge e2;
  798. node = false;
  799. Node n = new Node("Node");
  800. n.setPosition(x, y);
  801. controller.addObjectCanvas(n);
  802. AbstractCanvasObject r, k;
  803. r = p.getA();
  804. k = p.getB();
  805. e = new Edge(n, tempCps, model.getMaxCapacity());
  806. e1 = new Edge(n, r, model.getMaxCapacity());
  807. e2 = new Edge(n, k, model.getMaxCapacity());
  808. controller.removeEdgesOnCanvas(p);
  809. controller.addEdgeOnCanvas(e);
  810. controller.addEdgeOnCanvas(e1);
  811. controller.addEdgeOnCanvas(e2);
  812. }
  813. } else {
  814. mayBeReplaced = null;
  815. }
  816. // ins leere Gedragged
  817. if (node && !checkForReplacement(x, y)) {
  818. Node n = new Node("Node");
  819. n.setPosition(x, y);
  820. controller.addObjectCanvas(n);
  821. e = new Edge(n, tempCps, model.getMaxCapacity());
  822. controller.addEdgeOnCanvas(e);
  823. } else {
  824. mayBeReplaced = null;
  825. }
  826. // Wenn ein Node ohne Connections da ist
  827. if (deleteNode) {
  828. controller.delCanvasObject(tempCps, true);
  829. tempCps = null;
  830. }
  831. }
  832. }
  833. /**
  834. * Checks if the mouse is on an Edge.
  835. *
  836. * @param x Position of the Mouse
  837. * @param y Position of the Mouse
  838. * @return CpsEdge the Mouse is on, null if the mouse is not on an Edge
  839. */
  840. protected Edge mousePositionOnEdge(int x, int y) {
  841. x += controller.getScaleDiv2();
  842. y += controller.getScaleDiv2();
  843. for (Edge p : model.getEdgesOnCanvas()) {
  844. Line2D l = new Line2D.Float(p.getA().getPosition().getX(), p.getA().getPosition().getY(),
  845. p.getB().getPosition().getX(), p.getB().getPosition().getY());
  846. int[] positions = determineMousePositionOnEdge(p);
  847. int lx = positions[0];
  848. int ly = positions[1];
  849. int hx = positions[2];
  850. int hy = positions[3];
  851. // distance from a point to a line and between both Objects
  852. if (l.ptLineDistSq(x - Model.getScaleDiv2(), y - Model.getScaleDiv2()) < 20 && x > lx && x < hx && y > ly
  853. && y < hy) {
  854. return p;
  855. }
  856. }
  857. return null;
  858. }
  859. /**
  860. * set toolTip
  861. *
  862. * @param bool
  863. */
  864. public void setToolTip(boolean bool) {
  865. this.toolTip = bool;
  866. }
  867. /**
  868. * Set the Mouse
  869. *
  870. * @param x
  871. * @param y
  872. */
  873. public void setXY(int x, int y) {
  874. this.x = x;
  875. this.y = y;
  876. }
  877. @Override
  878. public boolean checkForReplacement(int x, int y) {
  879. return checkForReplacement(model.getObjectsOnCanvas(), null, x, y);
  880. }
  881. @Override
  882. public void tryToAlignObjects() {
  883. /**
  884. * Align all Objects
  885. */
  886. for (AbstractCanvasObject cps : model.getObjectsOnCanvas())
  887. align(cps, 3 * Model.getScaleDiv2());
  888. /**
  889. * AutoSave new Positons
  890. */
  891. try {
  892. controller.autoSave();
  893. } catch (IOException ex) {
  894. System.err.println("AutoSave error by aligning");
  895. ex.printStackTrace();
  896. }
  897. }
  898. @Override
  899. public void closeUpperNodeTab(int upperNodeId) {
  900. JTabbedPane tabbedPaneInner = (JTabbedPane) getParent().getParent().getParent().getParent();
  901. for (int i = 1; i < tabbedPaneInner.getTabCount(); i++) {
  902. if (((GroupNodeCanvas) ((JScrollPane) tabbedPaneInner.getComponentAt(i)).getViewport().getComponent(0))
  903. .getGroupNode().getId() == upperNodeId) {
  904. tabbedPaneInner.remove(i);
  905. break;
  906. }
  907. }
  908. }
  909. }