Canvas.java 34 KB

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