|
@@ -0,0 +1,867 @@
|
|
|
+package ui.view;
|
|
|
+
|
|
|
+import java.awt.BasicStroke;
|
|
|
+import java.awt.Color;
|
|
|
+import java.awt.Graphics;
|
|
|
+import java.awt.Graphics2D;
|
|
|
+import java.awt.Image;
|
|
|
+import java.awt.Point;
|
|
|
+import java.awt.Rectangle;
|
|
|
+import java.awt.RenderingHints;
|
|
|
+import java.awt.event.ActionEvent;
|
|
|
+import java.awt.event.ActionListener;
|
|
|
+import java.awt.event.MouseEvent;
|
|
|
+import java.awt.event.MouseListener;
|
|
|
+import java.awt.event.MouseMotionListener;
|
|
|
+import java.awt.geom.Line2D;
|
|
|
+import java.io.File;
|
|
|
+import java.io.IOException;
|
|
|
+import java.util.ArrayList;
|
|
|
+import java.util.Timer;
|
|
|
+import java.util.TimerTask;
|
|
|
+
|
|
|
+import javax.swing.ImageIcon;
|
|
|
+import javax.swing.JMenuItem;
|
|
|
+import javax.swing.JPanel;
|
|
|
+import javax.swing.JPopupMenu;
|
|
|
+import javax.swing.JToolTip;
|
|
|
+
|
|
|
+import api.CpsAPI;
|
|
|
+import classes.CpsEdge;
|
|
|
+import classes.CpsNode;
|
|
|
+import classes.CpsUpperNode;
|
|
|
+import classes.AbstractCpsObject;
|
|
|
+import classes.HolonElement;
|
|
|
+import classes.HolonObject;
|
|
|
+import classes.HolonSwitch;
|
|
|
+import classes.SubNet;
|
|
|
+import ui.controller.Control;
|
|
|
+import ui.model.Model;
|
|
|
+
|
|
|
+/**
|
|
|
+ * This Class is the Canvas. All Objects will be visualized here
|
|
|
+ *
|
|
|
+ * @author Gruppe14
|
|
|
+ */
|
|
|
+public class UpperNodeCanvas extends JPanel implements MouseListener, MouseMotionListener {
|
|
|
+
|
|
|
+ private static final long serialVersionUID = 1L;
|
|
|
+ private Image img = null; // Contains the image to draw on MyCanvas
|
|
|
+ private int x = 0;
|
|
|
+ private int y = 0;
|
|
|
+ // edge Object Start Point
|
|
|
+ private Model model;
|
|
|
+ private final Control controller;
|
|
|
+ Graphics2D g2; // For Painting
|
|
|
+ private int cx, cy;
|
|
|
+ private int sx, sy; // Mark Coords
|
|
|
+ private float scalediv20;
|
|
|
+
|
|
|
+ ArrayList<HolonElement> dataSelected = new ArrayList<HolonElement>();
|
|
|
+ ArrayList<AbstractCpsObject> tempSelected = new ArrayList<AbstractCpsObject>();
|
|
|
+
|
|
|
+ //The UpperNode
|
|
|
+ CpsUpperNode upperNode;
|
|
|
+
|
|
|
+ private boolean[] showedInformation = new boolean[3];
|
|
|
+ private boolean dragging = false; // for dragging
|
|
|
+ private boolean dragged = false; // if an object/objects was/were dragged
|
|
|
+ private boolean drawEdge = false; // for drawing edges
|
|
|
+ private boolean click = false; // for double click
|
|
|
+ private boolean doMark = false; // for double click
|
|
|
+ public AbstractCpsObject tempCps = null;
|
|
|
+ private CpsEdge edgeHighlight = null;
|
|
|
+
|
|
|
+ // PopUpMenu
|
|
|
+ private JPopupMenu popmenu = new JPopupMenu();
|
|
|
+ private JMenuItem itemDelete = new JMenuItem("Delete");
|
|
|
+ private JMenuItem itemCut = new JMenuItem("Cut");
|
|
|
+ private JMenuItem itemCopy = new JMenuItem("Copy");
|
|
|
+ public JMenuItem itemPaste = new JMenuItem("Paste");
|
|
|
+ public JMenuItem itemCollapse = new JMenuItem("Colapse Nodes");
|
|
|
+ public JMenuItem itemTrack = new JMenuItem("Track");
|
|
|
+ public JMenuItem itemUntrack = new JMenuItem("Untrack");
|
|
|
+ private JToolTip objectTT = new JToolTip();
|
|
|
+
|
|
|
+ private Point mousePosition = new Point(); // Mouse Position when
|
|
|
+ // rightclicked
|
|
|
+
|
|
|
+ // contains the value of the Capacity for new created Edges
|
|
|
+ private float edgeCapacity;
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Constructor.
|
|
|
+ *
|
|
|
+ * @param mod
|
|
|
+ * the Model
|
|
|
+ * @param control
|
|
|
+ * the Controller
|
|
|
+ */
|
|
|
+ public UpperNodeCanvas(Model mod, Control control, CpsUpperNode UpperNode) {
|
|
|
+ this.add(objectTT);
|
|
|
+ this.controller = control;
|
|
|
+ this.model = mod;
|
|
|
+
|
|
|
+ this.upperNode = UpperNode;
|
|
|
+
|
|
|
+ scalediv20 = model.getScale() / 20;
|
|
|
+
|
|
|
+ showedInformation[0] = true;
|
|
|
+ showedInformation[1] = true;
|
|
|
+ edgeCapacity = 10000;
|
|
|
+
|
|
|
+ popmenu.add(itemCut);
|
|
|
+ popmenu.add(itemCopy);
|
|
|
+ popmenu.add(itemPaste);
|
|
|
+ popmenu.add(itemDelete);
|
|
|
+ popmenu.addSeparator();
|
|
|
+ popmenu.add(itemCollapse);
|
|
|
+ popmenu.add(itemTrack);
|
|
|
+ popmenu.add(itemUntrack);
|
|
|
+
|
|
|
+ itemDelete.setEnabled(false);
|
|
|
+ itemCut.setEnabled(false);
|
|
|
+ itemCopy.setEnabled(false);
|
|
|
+ itemPaste.setEnabled(false);
|
|
|
+ itemCollapse.setEnabled(false);
|
|
|
+ itemTrack.setEnabled(false);
|
|
|
+ itemUntrack.setEnabled(false);
|
|
|
+
|
|
|
+ itemCollapse.addActionListener(new ActionListener() {
|
|
|
+ @Override
|
|
|
+ public void actionPerformed(ActionEvent e) {
|
|
|
+
|
|
|
+ repaint();
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+ itemTrack.addActionListener(new ActionListener() {
|
|
|
+ @Override
|
|
|
+ public void actionPerformed(ActionEvent e) {
|
|
|
+ for (AbstractCpsObject o : model.getSelectedCpsObjects()) {
|
|
|
+ if (o instanceof HolonObject) {
|
|
|
+ boolean found = false;
|
|
|
+ if (controller.getTrackingObj() != null) {
|
|
|
+ for (HolonObject obj : controller.getTrackingObj()) {
|
|
|
+ if (obj.getID() == o.getID()) {
|
|
|
+ found = true;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (!found) {
|
|
|
+ controller.addTrackingObj((HolonObject) o);
|
|
|
+ ((HolonObject) o).updateTrackingInfo();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ System.out.println(controller.getTrackingObj());
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+ itemUntrack.addActionListener(new ActionListener() {
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void actionPerformed(ActionEvent e) {
|
|
|
+ for (AbstractCpsObject o : model.getSelectedCpsObjects()) {
|
|
|
+ if (o instanceof HolonObject) {
|
|
|
+ boolean found = false;
|
|
|
+ if (controller.getTrackingObj() != null) {
|
|
|
+ for (HolonObject obj : controller.getTrackingObj()) {
|
|
|
+ if (obj.getID() == o.getID()) {
|
|
|
+ found = true;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (found) {
|
|
|
+ // Removed from tracking array and tracking
|
|
|
+ // information reseted
|
|
|
+ controller.removeTrackingObj((HolonObject) o);
|
|
|
+ ((HolonObject) o).setTrackingProd(new float[100]);
|
|
|
+ ((HolonObject) o).setTrackingCons(new float[100]);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ System.out.println(controller.getTrackingObj());
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+ itemDelete.addActionListener(new ActionListener() {
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void actionPerformed(ActionEvent e) {
|
|
|
+ // Remove the selected Object objects
|
|
|
+ for (AbstractCpsObject cps : model.getSelectedCpsObjects()) {
|
|
|
+ controller.delCanvasObject(cps);
|
|
|
+ }
|
|
|
+ model.getSelectedCpsObjects().clear();
|
|
|
+ tempCps = null;
|
|
|
+ repaint();
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+ itemCut.addActionListener(new ActionListener() {
|
|
|
+ @Override
|
|
|
+ public void actionPerformed(ActionEvent e) {
|
|
|
+ controller.cutObjects();
|
|
|
+ itemPaste.setEnabled(true);
|
|
|
+ repaint();
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+ itemCopy.addActionListener(new ActionListener() {
|
|
|
+ @Override
|
|
|
+ public void actionPerformed(ActionEvent e) {
|
|
|
+ controller.copyObjects();
|
|
|
+ itemPaste.setEnabled(true);
|
|
|
+ repaint();
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+ itemPaste.addActionListener(new ActionListener() {
|
|
|
+ @Override
|
|
|
+ public void actionPerformed(ActionEvent e) {
|
|
|
+ controller.pasteObjects(mousePosition);
|
|
|
+ repaint();
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+ this.addMouseListener(this);
|
|
|
+ this.addMouseMotionListener(this);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Paints all Components on the Canvas.
|
|
|
+ *
|
|
|
+ * @param g
|
|
|
+ * Graphics
|
|
|
+ */
|
|
|
+ public void paintComponent(Graphics g) {
|
|
|
+ String maxCap;
|
|
|
+ super.paintComponent(g);
|
|
|
+ // Rendering
|
|
|
+ g2 = (Graphics2D) g;
|
|
|
+ RenderingHints rh = new RenderingHints(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
|
|
|
+ g2.setRenderingHints(rh);
|
|
|
+
|
|
|
+ // Test SubNet Coloring
|
|
|
+ int i = 0;
|
|
|
+ for (SubNet s : controller.getSimManager().getSubNets()) {
|
|
|
+
|
|
|
+ if (model.getSubNetColors().size() - 1 < i) {
|
|
|
+ controller.addSubNetColor(new Color((int) (Math.random() * 255), (int) (Math.random() * 255),
|
|
|
+ (int) (Math.random() * 255)));
|
|
|
+ }
|
|
|
+
|
|
|
+ for (HolonObject cps : s.getObjects()) {
|
|
|
+ cps.setBorderColor(model.getSubNetColors().get(i));
|
|
|
+ }
|
|
|
+ i++;
|
|
|
+ }
|
|
|
+
|
|
|
+ // drawEdges that is being dragged
|
|
|
+ if (drawEdge) {
|
|
|
+ g2.setColor(Color.BLACK);
|
|
|
+ g2.setStroke(new BasicStroke(2));
|
|
|
+ g2.drawLine(tempCps.getPosition().x + controller.getScaleDiv2(),
|
|
|
+ tempCps.getPosition().y + controller.getScaleDiv2(), x, y);
|
|
|
+ }
|
|
|
+
|
|
|
+ for (CpsEdge con : model.getEdgesOnCanvas()) {
|
|
|
+ if (con.getA().getID() != model.getSelectedObjectID() && con.getB().getID() != model.getSelectedObjectID()
|
|
|
+ && con != edgeHighlight) {
|
|
|
+ if (con.getState()) {
|
|
|
+ g2.setColor(Color.GREEN);
|
|
|
+ if (con.getCapacity() != -1) {
|
|
|
+ g2.setStroke(new BasicStroke(Math.min((con.getFlow() / con.getCapacity() * 4), 4)));
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ g2.setColor(Color.RED);
|
|
|
+ g2.setStroke(new BasicStroke(2));
|
|
|
+ }
|
|
|
+ g2.drawLine(con.getA().getPosition().x + controller.getScaleDiv2(),
|
|
|
+ con.getA().getPosition().y + controller.getScaleDiv2(),
|
|
|
+ con.getB().getPosition().x + controller.getScaleDiv2(),
|
|
|
+ con.getB().getPosition().y + controller.getScaleDiv2());
|
|
|
+
|
|
|
+ if (con.getCapacity() == -1) {
|
|
|
+ maxCap = Character.toString('\u221e');
|
|
|
+ } else {
|
|
|
+ maxCap = String.valueOf(con.getCapacity());
|
|
|
+ }
|
|
|
+ if (showedInformation[0]) {
|
|
|
+ g2.drawString(con.getFlow() + "/" + maxCap,
|
|
|
+ (con.getA().getPosition().x + con.getB().getPosition().x) / 2 + controller.getScaleDiv2(),
|
|
|
+ (con.getA().getPosition().y + con.getB().getPosition().y) / 2 + controller.getScaleDiv2());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // Highlighted Edge
|
|
|
+ if (model.getSelectedObjectID() > 0 || !model.getSelectedCpsObjects().isEmpty() || !tempSelected.isEmpty()) {
|
|
|
+ g2.setColor(Color.BLUE);
|
|
|
+ for (CpsEdge con : model.getEdgesOnCanvas()) {
|
|
|
+ if (con.getFlow() <= con.getCapacity()) {
|
|
|
+ g2.setStroke(new BasicStroke(Math.min((con.getFlow() / con.getCapacity() * 4), 4)));
|
|
|
+ } else {
|
|
|
+ g2.setStroke(new BasicStroke(2));
|
|
|
+ }
|
|
|
+ if (con.getA().getID() == model.getSelectedObjectID()
|
|
|
+ || model.getSelectedCpsObjects().contains(con.getA()) || tempSelected.contains(con.getA())
|
|
|
+ || con.getB().getID() == model.getSelectedObjectID()
|
|
|
+ || model.getSelectedCpsObjects().contains(con.getB())
|
|
|
+ || tempSelected.contains(con.getB()) && con != edgeHighlight) {
|
|
|
+ g2.drawLine(con.getA().getPosition().x + controller.getScaleDiv2(),
|
|
|
+ con.getA().getPosition().y + controller.getScaleDiv2(),
|
|
|
+ con.getB().getPosition().x + controller.getScaleDiv2(),
|
|
|
+ con.getB().getPosition().y + controller.getScaleDiv2());
|
|
|
+
|
|
|
+ if (con.getCapacity() == -1) {
|
|
|
+ maxCap = Character.toString('\u221e');
|
|
|
+ } else {
|
|
|
+ maxCap = String.valueOf(con.getCapacity());
|
|
|
+ }
|
|
|
+ if (showedInformation[0]) {
|
|
|
+ g2.drawString(con.getFlow() + "/" + maxCap,
|
|
|
+ (con.getA().getPosition().x + con.getB().getPosition().x) / 2
|
|
|
+ + controller.getScaleDiv2(),
|
|
|
+ (con.getA().getPosition().y + con.getB().getPosition().y) / 2
|
|
|
+ + controller.getScaleDiv2());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } else if (edgeHighlight != null) {
|
|
|
+ g2.setColor(Color.BLUE);
|
|
|
+ if (edgeHighlight.getFlow() <= edgeHighlight.getCapacity()) {
|
|
|
+ g2.setStroke(new BasicStroke(Math.min((edgeHighlight.getFlow() / edgeHighlight.getCapacity() * 4), 4)));
|
|
|
+ } else {
|
|
|
+ g2.setStroke(new BasicStroke(2));
|
|
|
+ }
|
|
|
+ g2.drawLine(edgeHighlight.getA().getPosition().x + controller.getScaleDiv2(),
|
|
|
+ edgeHighlight.getA().getPosition().y + controller.getScaleDiv2(),
|
|
|
+ edgeHighlight.getB().getPosition().x + controller.getScaleDiv2(),
|
|
|
+ edgeHighlight.getB().getPosition().y + controller.getScaleDiv2());
|
|
|
+
|
|
|
+ if (edgeHighlight.getCapacity() == -1) {
|
|
|
+ maxCap = Character.toString('\u221e');
|
|
|
+ } else {
|
|
|
+ maxCap = String.valueOf(edgeHighlight.getCapacity());
|
|
|
+ }
|
|
|
+ if (showedInformation[0]) {
|
|
|
+ g2.drawString(edgeHighlight.getFlow() + "/" + maxCap,
|
|
|
+ (edgeHighlight.getA().getPosition().x + edgeHighlight.getB().getPosition().x) / 2
|
|
|
+ + controller.getScaleDiv2(),
|
|
|
+ (edgeHighlight.getA().getPosition().y + edgeHighlight.getB().getPosition().y) / 2
|
|
|
+ + controller.getScaleDiv2());
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // Objects
|
|
|
+ for (AbstractCpsObject cps : upperNode.getNodes()) {
|
|
|
+ // Border Highlighting
|
|
|
+ g2.setColor(cps.getBorderColor());
|
|
|
+ if (g2.getColor() != Color.WHITE) {
|
|
|
+ g2.fillRect((int) (cps.getPosition().x - scalediv20 - 3), (int) (cps.getPosition().y - scalediv20 - 3),
|
|
|
+ (int) (controller.getScale() + ((scalediv20 + 3) * 2)),
|
|
|
+ (int) (controller.getScale() + ((scalediv20 + 3) * 2)));
|
|
|
+ }
|
|
|
+
|
|
|
+ // node image
|
|
|
+ if (cps instanceof CpsNode && (cps == tempCps || model.getSelectedCpsObject() == cps
|
|
|
+ || model.getSelectedCpsObjects().contains(cps) || tempSelected.contains(cps))) {
|
|
|
+ img = new ImageIcon(this.getClass().getResource("/Images/node_selected.png")).getImage();
|
|
|
+ } else {
|
|
|
+ if (cps instanceof HolonSwitch) {
|
|
|
+ if (((HolonSwitch) cps).getActiveAt()[model.getCurIteration()]) {
|
|
|
+ ((HolonSwitch) cps).setAutoState(true);
|
|
|
+ } else {
|
|
|
+ ((HolonSwitch) cps).setAutoState(false);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ // Highlighting
|
|
|
+ if ((cps == tempCps && model.getSelectedCpsObjects().size() == 0 && tempSelected.size() == 0)
|
|
|
+ || model.getSelectedCpsObjects().contains(cps) || tempSelected.contains(cps)) {
|
|
|
+ g2.setColor(Color.BLUE);
|
|
|
+ g2.fillRect((int) (cps.getPosition().x - scalediv20), (int) (cps.getPosition().y - scalediv20),
|
|
|
+ (int) (controller.getScale() + (scalediv20 * 2)),
|
|
|
+ (int) (controller.getScale() + (scalediv20 * 2)));
|
|
|
+ if (showedInformation[1] && cps instanceof HolonObject) {
|
|
|
+ g2.setColor(Color.BLACK);
|
|
|
+ float totalEnergy = ((HolonObject) cps).getCurrentEnergyAtTimeStep(model.getCurIteration());
|
|
|
+ g2.drawString(Float.toString(totalEnergy), cps.getPosition().x, cps.getPosition().y - 10);
|
|
|
+ }
|
|
|
+ } else if (cps instanceof HolonObject) {
|
|
|
+ g2.setColor(((HolonObject) cps).getColor());
|
|
|
+
|
|
|
+ g2.fillRect((int) (cps.getPosition().x - scalediv20), (int) (cps.getPosition().y - scalediv20),
|
|
|
+ (int) (controller.getScale() + (scalediv20 * 2)),
|
|
|
+ (int) (controller.getScale() + (scalediv20 * 2)));
|
|
|
+
|
|
|
+ if (showedInformation[1]) {
|
|
|
+ g2.setColor(Color.BLACK);
|
|
|
+ float totalEnergy = ((HolonObject) cps).getCurrentEnergyAtTimeStep(model.getCurIteration());
|
|
|
+ g2.drawString(Float.toString(totalEnergy), cps.getPosition().x, cps.getPosition().y - 10);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ // draw image
|
|
|
+ File checkPath = new File(cps.getImage());
|
|
|
+ if (checkPath.exists()) {
|
|
|
+ img = new ImageIcon(cps.getImage()).getImage();
|
|
|
+ } else {
|
|
|
+ img = new ImageIcon(this.getClass().getResource(cps.getImage())).getImage();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ g2.drawImage(img, cps.getPosition().x, cps.getPosition().y, controller.getScale(), controller.getScale(),
|
|
|
+ null);
|
|
|
+ }
|
|
|
+
|
|
|
+ // Dragg Highlighting
|
|
|
+ if (doMark) {
|
|
|
+ g2.setColor(Color.BLACK);
|
|
|
+ g2.setStroke(new BasicStroke(1));
|
|
|
+ if (sx > x && sy > y) {
|
|
|
+ g2.drawRect(x, y, sx - x, sy - y);
|
|
|
+ } else if (sx < x && sy < y) {
|
|
|
+ g2.drawRect(sx, sy, x - sx, y - sy);
|
|
|
+ } else if (sx >= x) {
|
|
|
+ g2.drawRect(x, sy, sx - x, y - sy);
|
|
|
+ } else if (sy >= y) {
|
|
|
+ g2.drawRect(sx, y, x - sx, sy - y);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void mouseClicked(MouseEvent e) {
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void mouseEntered(MouseEvent e) {
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void mouseExited(MouseEvent e) {
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void mousePressed(MouseEvent e) {
|
|
|
+ tempCps = null;
|
|
|
+ dataSelected = null;
|
|
|
+ edgeHighlight = null;
|
|
|
+ controller.setSelecteEdge(null);
|
|
|
+ // Object Selection
|
|
|
+ for (AbstractCpsObject cps : upperNode.getNodes()) {
|
|
|
+ cx = cps.getPosition().x;
|
|
|
+ cy = cps.getPosition().y;
|
|
|
+ if (x - controller.getScale() <= cx && y - controller.getScale() <= cy && x >= cx && y >= cy) {
|
|
|
+ tempCps = cps;
|
|
|
+ controller.addTextToConsole("Selected: ", Color.BLACK, 12, false, false, false);
|
|
|
+ controller.addTextToConsole("" + cps.getName(), Color.BLUE, 12, true, false, false);
|
|
|
+ controller.addTextToConsole(", ID:", Color.BLACK, 12, false, false, false);
|
|
|
+ controller.addTextToConsole("" + cps.getID(), Color.RED, 12, true, false, true);
|
|
|
+ dragging = true;
|
|
|
+ controller.setSelectedObjectID(tempCps.getID());
|
|
|
+ // If drawing an Edge (CTRL down)
|
|
|
+ if (tempCps.getClass() == HolonObject.class) {
|
|
|
+ HolonObject tempObj = ((HolonObject) tempCps);
|
|
|
+ dataSelected = tempObj.getElements();
|
|
|
+ }
|
|
|
+ if (e.isShiftDown()) {
|
|
|
+ drawEdge = true;
|
|
|
+ dragging = false;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // Edge Selection
|
|
|
+ if (tempCps == null) {
|
|
|
+ edgeHighlight = mousePositionOnEdge(x, y);
|
|
|
+ controller.setSelecteEdge(edgeHighlight);
|
|
|
+ controller.setSelectedObjectID(0);
|
|
|
+ if (!e.isControlDown() && e.getButton() != MouseEvent.BUTTON3) {
|
|
|
+ model.getSelectedCpsObjects().clear();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (edgeHighlight == null && tempCps == null) {
|
|
|
+ sx = e.getX();
|
|
|
+ sy = e.getY();
|
|
|
+ doMark = true;
|
|
|
+ }
|
|
|
+
|
|
|
+ repaint();
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void mouseReleased(MouseEvent e) {
|
|
|
+ dragging = false;
|
|
|
+
|
|
|
+ if (drawEdge) {
|
|
|
+ drawEdge = false;
|
|
|
+ drawDeleteEdge();
|
|
|
+ }
|
|
|
+
|
|
|
+ if (dragged == true) {
|
|
|
+ try {
|
|
|
+ controller.autoSave();
|
|
|
+ } catch (IOException ex) {
|
|
|
+ // TODO Auto-generated catch block
|
|
|
+ ex.printStackTrace();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!e.isControlDown() && dragged == false && tempCps != null && e.BUTTON3 != e.getButton()) {
|
|
|
+ model.getSelectedCpsObjects().clear();
|
|
|
+ controller.addSelectedObject(tempCps);
|
|
|
+ }
|
|
|
+
|
|
|
+ dragged = false;
|
|
|
+
|
|
|
+ // Rightclick List
|
|
|
+ if (e.getButton() == MouseEvent.BUTTON3) {
|
|
|
+ if (e.getButton() == MouseEvent.BUTTON3 && tempCps != null) {
|
|
|
+ itemDelete.setEnabled(true);
|
|
|
+ itemCut.setEnabled(true);
|
|
|
+ itemCopy.setEnabled(true);
|
|
|
+ itemCollapse.setEnabled(true);
|
|
|
+ if (!(tempCps instanceof HolonSwitch)) {
|
|
|
+ itemTrack.setEnabled(true);
|
|
|
+ itemUntrack.setEnabled(true);
|
|
|
+ } else {
|
|
|
+ itemTrack.setEnabled(false);
|
|
|
+ itemUntrack.setEnabled(false);
|
|
|
+ }
|
|
|
+ if (model.getSelectedCpsObjects().size() == 0) {
|
|
|
+ controller.addSelectedObject(tempCps);
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ itemCut.setEnabled(false);
|
|
|
+ itemCopy.setEnabled(false);
|
|
|
+ itemDelete.setEnabled(false);
|
|
|
+ itemCollapse.setEnabled(false);
|
|
|
+ itemTrack.setEnabled(false);
|
|
|
+ itemUntrack.setEnabled(false);
|
|
|
+ }
|
|
|
+ mousePosition = this.getMousePosition();
|
|
|
+ popmenu.show(e.getComponent(), e.getX(), e.getY());
|
|
|
+ }
|
|
|
+
|
|
|
+ if (doMark) {
|
|
|
+ doMark = false;
|
|
|
+ for (AbstractCpsObject cps : tempSelected) {
|
|
|
+ if (!model.getSelectedCpsObjects().contains(cps)) {
|
|
|
+ controller.addSelectedObject(cps);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ tempSelected.clear();
|
|
|
+ }
|
|
|
+
|
|
|
+ if (doubleClick() && tempCps != null && tempCps instanceof HolonSwitch) {
|
|
|
+ ((HolonSwitch) tempCps).switchState();
|
|
|
+ }
|
|
|
+
|
|
|
+ controller.calculateStateForTimeStep(model.getCurIteration());
|
|
|
+
|
|
|
+ repaint();
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void mouseDragged(MouseEvent e) {
|
|
|
+ // If Edge is drawn
|
|
|
+ x = e.getX();
|
|
|
+ y = e.getY();
|
|
|
+ if (!model.getSelectedCpsObjects().contains(tempCps) && doMark == false) {
|
|
|
+ model.getSelectedCpsObjects().clear();
|
|
|
+ if (tempCps != null) {
|
|
|
+ controller.addSelectedObject(tempCps);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (dragging) {
|
|
|
+ try {
|
|
|
+ dragged = true;
|
|
|
+ float xDist, yDist; // Distance
|
|
|
+
|
|
|
+ x = e.getX() - controller.getScaleDiv2();
|
|
|
+ y = e.getY() - controller.getScaleDiv2();
|
|
|
+
|
|
|
+ // Make sure its in bounds
|
|
|
+ if (e.getX() < controller.getScaleDiv2())
|
|
|
+ x = 0;
|
|
|
+ else if (e.getX() > this.getWidth() - controller.getScaleDiv2())
|
|
|
+ x = this.getWidth() - controller.getScale();
|
|
|
+ if (e.getY() < controller.getScaleDiv2())
|
|
|
+ y = 0;
|
|
|
+ else if (e.getY() > this.getHeight() - controller.getScaleDiv2())
|
|
|
+ y = this.getHeight() - controller.getScale();
|
|
|
+
|
|
|
+ // Distance
|
|
|
+ xDist = x - tempCps.getPosition().x;
|
|
|
+ yDist = y - tempCps.getPosition().y;
|
|
|
+
|
|
|
+ tempCps.setPosition(x, y); // Drag Position
|
|
|
+ // TipText Position and name
|
|
|
+ objectTT.setTipText(tempCps.getName() + ", " + tempCps.getID());
|
|
|
+ objectTT.setLocation(x, y + controller.getScale());
|
|
|
+
|
|
|
+ // All Selected Objects
|
|
|
+ for (AbstractCpsObject cps : model.getSelectedCpsObjects()) {
|
|
|
+ if (cps != tempCps) {
|
|
|
+ x = (int) (cps.getPosition().x + xDist);
|
|
|
+ y = (int) (cps.getPosition().y + yDist);
|
|
|
+
|
|
|
+ // Make sure its in bounds
|
|
|
+ if (x <= 0)
|
|
|
+ x = 0;
|
|
|
+ else if (x > this.getWidth() - controller.getScale())
|
|
|
+ x = this.getWidth() - controller.getScale();
|
|
|
+ if (y <= 0)
|
|
|
+ y = 0;
|
|
|
+ else if (y > this.getHeight() - controller.getScale())
|
|
|
+ y = this.getHeight() - controller.getScale();
|
|
|
+
|
|
|
+ cps.setPosition(x, y);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ repaint();
|
|
|
+ } catch (Exception eex) {
|
|
|
+
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // Mark Objects
|
|
|
+ if (doMark) {
|
|
|
+ tempSelected.clear();
|
|
|
+ for (AbstractCpsObject cps : upperNode.getNodes()) {
|
|
|
+ int x1 = sx, x2 = x, y1 = sy, y2 = y;
|
|
|
+
|
|
|
+ if (sx >= x) {
|
|
|
+ x1 = x;
|
|
|
+ x2 = sx;
|
|
|
+ }
|
|
|
+ if (sy >= y) {
|
|
|
+ y1 = y;
|
|
|
+ y2 = sy;
|
|
|
+ }
|
|
|
+ if (x1 <= cps.getPosition().x + model.getScaleDiv2() && y1 <= cps.getPosition().y + model.getScaleDiv2()
|
|
|
+ && x2 >= cps.getPosition().x + model.getScaleDiv2()
|
|
|
+ && y2 >= cps.getPosition().y + model.getScaleDiv2()) {
|
|
|
+ tempSelected.add(cps);
|
|
|
+
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ repaint();
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void mouseMoved(MouseEvent e) {
|
|
|
+ x = e.getX();
|
|
|
+ y = e.getY();
|
|
|
+ // Everytghing for the tooltip :)
|
|
|
+ boolean on = false;
|
|
|
+ for (AbstractCpsObject cps : upperNode.getNodes()) {
|
|
|
+
|
|
|
+ cx = cps.getPosition().x;
|
|
|
+ cy = cps.getPosition().y;
|
|
|
+ if (x - controller.getScale() <= cx && y - controller.getScale() <= cy && x >= cx && y >= cy) {
|
|
|
+
|
|
|
+ objectTT.setTipText(cps.getName() + ", " + cps.getID());
|
|
|
+ objectTT.setLocation(cx, cy + controller.getScale());
|
|
|
+ on = true;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (!on) {
|
|
|
+ objectTT.setLocation(-200, -200);
|
|
|
+ objectTT.setTipText("");
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Draws or Deletes an Edge.
|
|
|
+ */
|
|
|
+ private void drawDeleteEdge() {
|
|
|
+ boolean node = true;
|
|
|
+ boolean newEdge = true;
|
|
|
+ boolean onEdge = true;
|
|
|
+ boolean deleteNode = false;
|
|
|
+ CpsEdge e = null;
|
|
|
+ AbstractCpsObject tempCPS = null;
|
|
|
+
|
|
|
+ for (AbstractCpsObject cps : upperNode.getNodes()) {
|
|
|
+ cx = cps.getPosition().x;
|
|
|
+ cy = cps.getPosition().y;
|
|
|
+ if (x - controller.getScale() <= cx && y - controller.getScale() <= cy && x >= cx && y >= cy
|
|
|
+ && cps != tempCps) {
|
|
|
+ node = false;
|
|
|
+ onEdge = false;
|
|
|
+ for (CpsEdge p : tempCps.getConnections()) {
|
|
|
+ if ((p.getA() == tempCps && p.getB() == cps) || (p.getB() == tempCps && p.getA() == cps)) {
|
|
|
+ newEdge = false;
|
|
|
+ e = p;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (!newEdge) {
|
|
|
+ controller.removeEdgesOnCanvas(e);
|
|
|
+ // Node ohne Edge?
|
|
|
+ if (e.getA().getClass() == CpsNode.class && e.getA().getConnections().isEmpty()) {
|
|
|
+ tempCps = e.getA();
|
|
|
+ deleteNode = true;
|
|
|
+ }
|
|
|
+ if (e.getB().getClass() == CpsNode.class && e.getB().getConnections().isEmpty()) {
|
|
|
+ tempCPS = e.getB();
|
|
|
+ deleteNode = true;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (newEdge) {
|
|
|
+ e = new CpsEdge(cps, tempCps, edgeCapacity);
|
|
|
+ controller.addEdgeOnCanvas(e);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ // Edge auf eine Edge gezogen?
|
|
|
+ if (onEdge) {
|
|
|
+ CpsEdge p = mousePositionOnEdge(x, y);
|
|
|
+ if (p != null) {
|
|
|
+ CpsEdge e1 = null;
|
|
|
+ CpsEdge e2 = null;
|
|
|
+
|
|
|
+ node = false;
|
|
|
+
|
|
|
+ CpsNode n = new CpsNode("Node");
|
|
|
+
|
|
|
+ n.setPosition(x - model.getScaleDiv2(), y - model.getScaleDiv2());
|
|
|
+ controller.addObjectCanvas(n);
|
|
|
+
|
|
|
+ AbstractCpsObject r, k;
|
|
|
+ r = p.getA();
|
|
|
+ k = p.getB();
|
|
|
+
|
|
|
+ e = new CpsEdge(n, tempCps, edgeCapacity);
|
|
|
+
|
|
|
+ e1 = new CpsEdge(n, r, edgeCapacity);
|
|
|
+
|
|
|
+ e2 = new CpsEdge(n, k, edgeCapacity);
|
|
|
+
|
|
|
+ controller.removeEdgesOnCanvas(p);
|
|
|
+ controller.addEdgeOnCanvas(e);
|
|
|
+ controller.addEdgeOnCanvas(e1);
|
|
|
+ controller.addEdgeOnCanvas(e2);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // ins leere Gedragged
|
|
|
+ if (node) {
|
|
|
+ CpsNode n = new CpsNode("Node");
|
|
|
+
|
|
|
+ n.setPosition(x - model.getScaleDiv2(), y - model.getScaleDiv2());
|
|
|
+ controller.addObjectCanvas(n);
|
|
|
+
|
|
|
+ e = new CpsEdge(n, tempCps, edgeCapacity);
|
|
|
+
|
|
|
+ controller.addEdgeOnCanvas(e);
|
|
|
+ }
|
|
|
+
|
|
|
+ // Wenn ein Node ohne Connections da ist
|
|
|
+ if (deleteNode) {
|
|
|
+ controller.delCanvasObject(tempCps);
|
|
|
+ tempCps = null;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Checks if the mouse is on an Edge.
|
|
|
+ *
|
|
|
+ * @param x
|
|
|
+ * Position of the Mouse
|
|
|
+ * @param y
|
|
|
+ * Position of the Mouse
|
|
|
+ *
|
|
|
+ * @return CpsEdge the Mouse is on, null if the mouse is not on an Edge
|
|
|
+ */
|
|
|
+ public CpsEdge mousePositionOnEdge(int x, int y) {
|
|
|
+ int lx, ly, hx, hy;
|
|
|
+ for (CpsEdge p : model.getEdgesOnCanvas()) {
|
|
|
+ Line2D l = new Line2D.Float(p.getA().getPosition().x, p.getA().getPosition().y, p.getB().getPosition().x,
|
|
|
+ p.getB().getPosition().y);
|
|
|
+ if (p.getA().getPosition().x > p.getB().getPosition().x) {
|
|
|
+ hx = p.getA().getPosition().x + model.getScaleDiv2() + 7;
|
|
|
+ lx = p.getB().getPosition().x + model.getScaleDiv2() - 7;
|
|
|
+ } else {
|
|
|
+ lx = p.getA().getPosition().x + model.getScaleDiv2() - 7;
|
|
|
+ hx = p.getB().getPosition().x + model.getScaleDiv2() + 7;
|
|
|
+ }
|
|
|
+ if (p.getA().getPosition().y > p.getB().getPosition().y) {
|
|
|
+ hy = p.getA().getPosition().y + model.getScaleDiv2() + 7;
|
|
|
+ ly = p.getB().getPosition().y + model.getScaleDiv2() - 7;
|
|
|
+ } else {
|
|
|
+ ly = p.getA().getPosition().y + model.getScaleDiv2() - 7;
|
|
|
+ hy = p.getB().getPosition().y + model.getScaleDiv2() + 7;
|
|
|
+ }
|
|
|
+
|
|
|
+ // distance from a point to a line and between both Objects
|
|
|
+ if (l.ptLineDistSq(x - model.getScaleDiv2(), y - model.getScaleDiv2()) < 20 && x > lx && x < hx && y > ly
|
|
|
+ && y < hy) {
|
|
|
+ return p;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Checks if a double click was made.
|
|
|
+ *
|
|
|
+ * @return true if doublecklick, false if not
|
|
|
+ */
|
|
|
+ private boolean doubleClick() {
|
|
|
+ if (click) {
|
|
|
+ click = false;
|
|
|
+ return true;
|
|
|
+ } else {
|
|
|
+ click = true;
|
|
|
+ Timer t = new Timer("doubleclickTimer", false);
|
|
|
+ t.schedule(new TimerTask() {
|
|
|
+ @Override
|
|
|
+ public void run() {
|
|
|
+ click = false;
|
|
|
+ }
|
|
|
+ }, 500);
|
|
|
+ }
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * sets the Edge Capacity.
|
|
|
+ *
|
|
|
+ * @param cap
|
|
|
+ * capacity
|
|
|
+ */
|
|
|
+ public void setEdgeCapacity(float cap) {
|
|
|
+ edgeCapacity = cap;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Set if Information should be shown.
|
|
|
+ *
|
|
|
+ * @param connection
|
|
|
+ * boolean for conecction
|
|
|
+ * @param object
|
|
|
+ * boolean for objects
|
|
|
+ */
|
|
|
+ public void setShowedInformation(boolean connection, boolean object) {
|
|
|
+ showedInformation[0] = connection;
|
|
|
+ showedInformation[1] = object;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Returns if Information should be shown.
|
|
|
+ *
|
|
|
+ * @return Array of boolean [0] = connection, [1] = objects
|
|
|
+ */
|
|
|
+ public boolean[] getShowedInformation() {
|
|
|
+ return showedInformation;
|
|
|
+ }
|
|
|
+
|
|
|
+}
|