Canvas.java 33 KB

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