package ui.view; import classes.*; import classes.comparator.UnitGraphPointComperator; import interfaces.GraphEditable; import interfaces.GraphEditable.Graphtype; import interfaces.IGraphedElement; import sun.reflect.generics.reflectiveObjects.NotImplementedException; import ui.controller.Control; import ui.controller.SingletonControl; import ui.model.Model; import javax.swing.*; import java.awt.*; import java.awt.event.*; import java.awt.geom.CubicCurve2D; import java.awt.geom.GeneralPath; import java.awt.geom.Line2D; import java.awt.geom.Path2D; import java.awt.geom.Point2D; import java.util.ArrayDeque; import java.util.ArrayList; import java.util.Iterator; import java.util.LinkedList; import java.util.ListIterator; /** * This Class represents a Graph where the User can model the behavior of * elements and switches over time. * * @author Gruppe14 */ public class UnitGraph extends JPanel implements MouseListener, MouseMotionListener, ComponentListener { private static final long serialVersionUID = 1L; public static final int STANDARD_GRAPH_ACCURACY = 100; private GeneralPath graphCurve = new GeneralPath(); private float maximum = 0; // Information shown when a Point is Dragged private String dragInformation = ""; // Points private Point recSize = new Point(8, 8); // Point Size private Graphics2D g2; private CubicCurve2D c = new CubicCurve2D.Double(); private CubicCurve2D cr = new CubicCurve2D.Double(); private CubicCurve2D cl = new CubicCurve2D.Double(); private LinkedList pointList; // Scale for the Graph private double scaleX; private double scaleY; private double width = -1; private double height = -1; private boolean isElement = false; private boolean isSwitch = false; private ArrayList tempElements = new ArrayList<>(); private Model model; private Control controller; private Line2D.Double line = null; private boolean pointDrag = false; private boolean init = true; private Point tempP = null; private double x = 0, y = 0; private int x1, x2, y1, y2, ctrlx1, ctrly1, ctrlx2, ctrly2; private int textWidth = 0; private IGraphedElement current; //NEW ERA // Normal Settings private int border = 4; private int clickThreshholdSquared = 25; // Display Settings /** * The size of a dot in the graph. * It should be at least 1. * */ int dotSize = 8; /** The Color of a dot in the graph. */ Color dotColor = Color.blue; //Intern Variables //TODO: JavaDoc private LinkedList actualGraphPoints = new LinkedList(); /** * This is list is sortet in the y achsis */ private LinkedList representativePositions = new LinkedList(); private Graphtype actualGraphType; private GraphEditable actualElement; ListIterator iter; ListIterator iter2; Position currentPosition; private int widthWithBorder, heightWithBorder; /** * Constructor. * * @param model the Model * @param control the Controller */ public UnitGraph(final Model model, Control control) { setCursor(Cursor.getPredefinedCursor(Cursor.CROSSHAIR_CURSOR)); this.controller = control; this.model = model; this.pointList = new LinkedList<>(); this.setBackground(Color.WHITE); this.addMouseListener(this); this.addMouseMotionListener(this); this.addComponentListener(this); } /** * Paints all Components on the Canvas. * * @param g Graphics */ public void paintComponent(Graphics g) { super.paintComponent(g); //System.out.println("paint"); Graphics2D g2D = (Graphics2D) g; g2D.setColor(Color.BLACK); int höhe = this.getHeight(); int breite = this.getWidth(); g2D.setRenderingHints(new RenderingHints(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON)); g2D.setStroke(new BasicStroke(2)); // g2D.drawLine(0, 0,breite, höhe); //printDebug(); printDebugRepresentive(); g2D.setColor(dotColor); drawUnitGraphPoints(g2D); g2D.setColor(Color.BLACK); drawUnitGraph(g2D); //generate Path --> maybe als Methode auslagern //Good Source for basic understanding for Bezier Curves //http://www.theappguruz.com/blog/bezier-curve-in-games Path2D.Double mypath = new Path2D.Double(); Position punktStart = new Position(+40,40); Position punktEnd = new Position(breite-180,höhe-90); //Werden Bestimmt //Erster Punkt bleibt in Höhe gleich aber nimmt die Hälfte der Breite zu mypath.moveTo(punktStart.x, punktStart.y); double mitte = (punktStart.x + punktEnd.x)* 0.5; mypath.curveTo(mitte, punktStart.y, mitte, punktEnd.y, punktEnd.x, punktEnd.y); g2D.draw(mypath); g2D.setColor(Color.BLUE); drawDot(g2D,punktStart); drawDot(g2D,punktEnd); // g2 = (Graphics2D) g; // RenderingHints rh = new RenderingHints(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); // g2.setRenderingHints(rh); // g2.setStroke(new BasicStroke(0)); // // graphCurve.reset(); // // border = (int) recSize.getX() >> 1; // // Draw the Vertical Lines // g2.setColor(Color.BLACK); // for (int i = border; i < this.getWidth() - border; i += border * 2) { // g2.drawLine(i, border, i, this.getHeight() - border); // } // g2.drawLine(this.getWidth() - border, border, this.getWidth() - border, this.getHeight() - border); // // for (int i = border; i < this.getHeight() - border; i += border * 2) { // g2.drawLine(border, i, this.getWidth() - border, i); // } // g2.drawLine(border, this.getHeight() - border, this.getWidth() - border, this.getHeight() - border); // // int effectiveX; // if(current!=null)effectiveX=getEffectiveIndex(model, current, model.getCurIteration()); // else effectiveX=0; // // if (isElement) { // // fill array with values from the pointList in a HolonElement // generateSampleCurves(); // // if (current != null) { // // Draw the Lines // g2.setStroke(new BasicStroke(2)); // g2.setColor(Color.BLACK); // for (int i = 0; i < pointList.size() - 1; i++) { // c = buildCurve(pointList.get(i), pointList.get(i + 1)); // c.setCurve((x1 * scaleX) + border, (y1 * scaleY) + border, (ctrlx1 * scaleX) + border, // (ctrly1 * scaleY) + border, (ctrlx2 * scaleX) + border, (ctrly2 * scaleY) + border, // (x2 * scaleX) + border, (y2 * scaleY) + border); // graphCurve.append(c, true); // } // g2.draw(graphCurve); // // // Draw the Points // g2.setColor(Color.BLUE); // for (Point aPointList : pointList) { // g2.fillOval((int) (aPointList.getX() * scaleX - recSize.getX() / 2) + border, // (int) (aPointList.getY() * scaleY - recSize.getY() / 2) + border, // (int) recSize.getX(), (int) recSize.getY()); // } // // // Iteration Value // //TODO: added function getGraphIterations see if it works // textWidth = g.getFontMetrics().stringWidth("" + ((HolonElement)current).getAvailableEnergyAt(model.getCurIteration())/*arrayOfFloats[effectiveX]*/) + 2; // if (textWidth // + (effectiveX) * (this.getWidth() - (border * 2)) / (/*model.getIterations()*/100 - 1) + 2 // + border <= this.getWidth()) { // g2.drawString("" + ((HolonElement)current).getAvailableEnergyAt(model.getCurIteration()), // (effectiveX) * (this.getWidth() - (border * 2)) / (/*model.getIterations()*/100 - 1) // + 2 + border, // this.getHeight() - 10); // } else { // g2.drawString("" + ((HolonElement)current).getAvailableEnergyAt(model.getCurIteration()), // (effectiveX) * (this.getWidth() - (border * 2)) / (/*model.getIterations()*/100 - 1) // + border - textWidth, // this.getHeight() - 10); // } // // } // // drag Information // if (tempP != null && pointDrag) { // dragInformation = "" + convertToValueY(getYValueAt((int) tempP.getX())); // textWidth = g.getFontMetrics().stringWidth("" + convertToValueY(getYValueAt((int) tempP.getX()))) + 2; // if (textWidth + (tempP.getX() * scaleX) + 10 + border <= this.getWidth()) { // g2.drawString(dragInformation, (int) (tempP.getX() * scaleX) + 10 + border, // (int) (tempP.getY() * scaleY) + 10); // } else { // g2.drawString(dragInformation, (int) (tempP.getX() * scaleX) - textWidth, // (int) (tempP.getY() * scaleY) + 10); // } // } // // /* // * // Actual Iteration Point Visualization g2.setColor(Color.RED); // * if (arrayOfFloats != null) { for (int i = 0; i < // * arrayOfFloats.length; i++) { g2.fillOval((int) (i * width / // * (model.getIterations() - 1) * scaleX - recSize.getX() / // * 2)+border, (int) (convertToCanvasY((int) arrayOfFloats[i]) * // * scaleY - recSize.getY() / 2)+border, (int) recSize.getX(), (int) // * recSize.getY()); } } // */ // // } else if (isSwitch) { // if (/*arrayOfBooleans*/current != null) {//Technically this test should be unnecessary // // array fillen // fillArrayofBooleans(); // // // Draw the Lines // g2.setStroke(new BasicStroke(2)); // g2.setColor(Color.BLACK); // for (int i = 0; i < pointList.size() - 1; i++) { // // Left out of bounce // if ((i == 1 || i == 2) && pointList.get(i).getX() < 0) { // line = new Line2D.Double(border, pointList.get(i).getY() * scaleY, border, // pointList.get(i + 1).getY() * scaleY); // } // // Right out of bounce // else if (i == pointList.size() - 4 && pointList.get(pointList.size() - 3).getX() > width) { // line = new Line2D.Double(pointList.get(i).getX() * scaleX + border, // pointList.get(i).getY() * scaleY, this.getWidth() - border, // pointList.get(i + 1).getY() * scaleY); // } else if (i == pointList.size() - 3 && pointList.get(pointList.size() - 3).getX() > width) { // line = new Line2D.Double(this.getWidth() - border, pointList.get(i).getY() * scaleY, // this.getWidth() - border, pointList.get(i + 1).getY() * scaleY); // } else if (i == pointList.size() - 2 && pointList.get(pointList.size() - 2).getX() > width) { // line = new Line2D.Double(this.getWidth() - border, pointList.get(i).getY() * scaleY, // pointList.get(i + 1).getX() * scaleX + border, pointList.get(i + 1).getY() * scaleY); // } else { // line = new Line2D.Double(pointList.get(i).getX() * scaleX + border, // pointList.get(i).getY() * scaleY, pointList.get(i + 1).getX() * scaleX + border, // pointList.get(i + 1).getY() * scaleY); // } // graphCurve.append(line, true); // } // g2.draw(graphCurve); // // /* // * // Draw the Points g2.setColor(Color.BLUE); for (int i = 0; i // * < pointList.size() - 0; i++) { g2.fillOval((int) // * (pointList.get(i).getX() * scaleX - recSize.getX() / 2) + // * border, (int) (pointList.get(i).getY() * scaleY - // * recSize.getY() / 2), (int) recSize.getX(), (int) // * recSize.getY()); } // */ // // // Iteration Value // g2.setColor(Color.BLUE); // textWidth = g.getFontMetrics().stringWidth("" + ((HolonSwitch)current).getState(model.getCurIteration())/*arrayOfBooleans[effectiveX]*/) + 2; // if (textWidth // + (effectiveX) * (this.getWidth() - (border * 2)) / (/*model.getIterations()*/100 - 1) + 2 // + border <= this.getWidth()) { // g2.drawString("" + ((HolonSwitch)current).getState(model.getCurIteration()), // (effectiveX) * (this.getWidth() - (border * 2)) / (/*model.getIterations()*/100 - 1) // + 2 + border, // this.getHeight() - 10); // } else { // g2.drawString("" + ((HolonSwitch)current).getState(model.getCurIteration()), // (effectiveX) * (this.getWidth() - (border * 2)) / (/*model.getIterations()*/100 - 1) // + border - textWidth, // this.getHeight() - 10); // } // // } // // When the switch graph is dragged // if (tempP != null && pointDrag) // // { // try { // int i; // for (i = 0; (i * (this.getWidth() - (border * 2)) / (/*model.getIterations()*/100 - 1) // + border < getMousePosition().getX()); i++) { // } // dragInformation = "" + i; // textWidth = g.getFontMetrics().stringWidth("" + convertToValueY(getYValueAt((int) tempP.getX()))) // + 2; // if (textWidth + (tempP.getX() * scaleX) + 10 + border <= this.getWidth()) { // g2.drawString(dragInformation, (int) (getMousePosition().getX()) + 10 + border, // (int) (getMousePosition().getY() * scaleY) + 10); // } else { // g2.drawString(dragInformation, (int) (getMousePosition().getX()) - textWidth, // (int) (getMousePosition().getY() * scaleY) + 10); // } // } catch (Exception e) { // } // } // } // // // Iteration Line TODO: repeat // g2.setColor(Color.BLUE); // g2.setStroke(new BasicStroke(1)); // g2.drawLine(border + (effectiveX) * (this.getWidth() - border * 2) / /*(model.getIterations() - 1)*/100-1, // 0, border + (effectiveX) * (this.getWidth() - border * 2) / /*(model.getIterations() - 1)*/100-1, // this.getHeight()); // // // algorithmus // controller.calculateStateForTimeStep(model.getCurIteration()); } //TODO -> New Section private void drawDot(Graphics2D g, Position p) { g.fillOval(p.x -dotSize/2, p.y-dotSize/2, dotSize, dotSize); } private Position convertToPosition(UnitGraphPoint p) { //Relativ to Border //1-p.y because its on the Top return new Position((int) (p.x * widthWithBorder) + border, (int) ((1-p.y) * heightWithBorder) + border); } private void drawUnitGraph(Graphics2D g) { switch(actualGraphType) { case boolGraph: drawBoolGraph(g); break; case doubleGraph: drawDoubleGraph(g); break; default: throw new UnsupportedOperationException(); } } private void drawUnitGraphPoints(Graphics2D g) { for(UnitGraphPoint p : actualGraphPoints){ if (p.changed) { g.setColor(Color.red); } else { g.setColor(Color.blue); } drawDot(g, p.displayedPosition); } } private void drawBoolGraph(Graphics2D g) { throw new NotImplementedException(); } private void updateRepresentativePositions() { for(UnitGraphPoint p : actualGraphPoints) { p.calcDisplayedPosition(border, widthWithBorder, heightWithBorder); } } private void drawDoubleGraph(Graphics2D g) { } private void overrideUnitGraph(LinkedList stateCurve) { actualGraphPoints.clear(); for(Point2D.Double p: stateCurve){ actualGraphPoints.add(new UnitGraphPoint(p)); } updateRepresentativePositions(); } private void calculateWidthHeight() { widthWithBorder = this.getWidth() - 2 * border; heightWithBorder = this.getHeight() - 2 * border; } public void initNewElement(GraphEditable element) { overrideUnitGraph(element.getStateGraph()); actualGraphType = element.getGraphType(); actualElement = element; repaint(); } private void printDebug(){ if(actualGraphPoints.isEmpty()) return; System.out.print("{"); for(UnitGraphPoint p: actualGraphPoints){ System.out.print(p); } System.out.println("}"); } private void printDebugRepresentive(){ if(this.actualGraphPoints.isEmpty()) return; System.out.print("{"); for(UnitGraphPoint p: actualGraphPoints){ System.out.print(p.displayedPosition); } System.out.println("}"); } private boolean detectPointUnderCurser(MouseEvent mEvent) { //get mouse Position Position mPosition = new Position(mEvent.getPoint()); //iter = representativePositions.listIterator(); iter2 = actualGraphPoints.listIterator(); while (iter2.hasNext()) { Position tempPosition = iter2.next().displayedPosition; if(mPosition.squareDistance(tempPosition) < clickThreshholdSquared) { currentPosition = tempPosition; return true; } } return false; } private void updateGraphPoint(Position newPosition) { //make it in the bounds of the UnitGraph no Point out of the Border currentPosition = setInBounds(newPosition); iter2.set(generateUnitGraphPoint(currentPosition)); repaint(); } private Position setInBounds(Position p) { p.clampX(border, border + widthWithBorder); p.clampY(border, border + heightWithBorder); return p; } private void insertNewGraphPoint(Position pos) { System.out.println("insertNewGraphPoint"); setInBounds(pos); iter2 = actualGraphPoints.listIterator(); while (iter2.hasNext()) { Position tempPosition = iter2.next().displayedPosition; if(pos.x <= tempPosition.x) { //First previous to go back a position to make the new point before the the Position with greater X iter2.previous(); iter2.add(generateUnitGraphPoint(pos)); //Second Previous to select the new added Position iter2.previous(); break; } } } private UnitGraphPoint generateUnitGraphPoint(Position pos) { UnitGraphPoint temp = new UnitGraphPoint((double)(pos.x - border)/(double)widthWithBorder,1 - (double) (pos.y - border)/(double)heightWithBorder,true); temp.displayedPosition = pos; return temp; } @Override public void mouseDragged(MouseEvent e) { System.out.println("MouseDragged"); //System.out.println("PositionFromITERATOR= "+ currentPosition +" Index= " + iter.previousIndex() ); updateGraphPoint(new Position(e.getPoint())); //printDebugRepresentive(); // if (isElement) { // elementDragged(e); // } else if (isSwitch) { // switchDragged(e); // } } /** * When a Point of a Holon Element is dragged. * * @param e MouseEvent */ public void elementDragged(MouseEvent e) { System.out.println("elementDragged"); // if (pointDrag && tempP != null) { // // Out of Bounds verhindern // int i = pointList.indexOf(tempP); // x = (e.getX() - border) / scaleX; // y = (e.getY() - border) / scaleY; // // y // if (e.getY() <= border) { // y = 0; // } else if (this.getHeight() - border <= e.getY()) { // y = (this.getHeight() - border * 2) / scaleY; // } // // x // if (tempP == pointList.getFirst() || tempP == pointList.getLast() || pointList.get(i + 1).getX() < x + 2 // || pointList.get(i - 1).getX() > x - 2 || pointList.getFirst().getX() > x - 2 // || pointList.getLast().getX() < x + 2) { // x = tempP.getX(); // } // tempP.setLocation(x, y); // // repaint(); // } } /** * When a Point of a switch is dragged. * * @param e MouseEvent */ public void switchDragged(MouseEvent e) { System.out.println("switchDragged"); // if (pointDrag && tempP != null && tempP != pointList.getFirst() && tempP != pointList.getLast()) { // int i = pointList.indexOf(tempP); // x = (e.getX() - border) / scaleX; // // if (pointList.get(i + 1).getY() == tempP.getY()) { // // x // if (pointList.get(i + 1).getX() <= x + 1 || pointList.get(i - 2).getX() >= x - 1) { // x = tempP.getX(); // } // pointList.get(i - 1).setLocation(x, pointList.get(i - 1).getY()); // } else { // // x // if (pointList.get(i + 2).getX() <= x + 1 || pointList.get(i - 1).getX() >= x - 1) { // x = tempP.getX(); // } // pointList.get(i + 1).setLocation(x, pointList.get(i + 1).getY()); // } // tempP.setLocation(x, tempP.getY()); // repaint(); // } } @Override public void mouseMoved(MouseEvent e) { } @Override public void mouseClicked(MouseEvent e) { System.out.println("mouseClicked"); } @Override public void mouseEntered(MouseEvent e) { } @Override public void mouseExited(MouseEvent e) { } @Override public void mousePressed(MouseEvent e) { System.out.println("mousePressed"); if (detectPointUnderCurser(e)) { //DoNothing } else { //create new Position this.insertNewGraphPoint(new Position(e.getPoint())); repaint(); } } /** * When a point of a Holon Element is pressed. * * @param e MouseEvent */ public void elementPressed(MouseEvent e) { System.out.println("elementPressed"); // // boolean added = false; // boolean deletePoint = false; // // int x = (int) ((e.getX() - border) / scaleX); // double y = (e.getY() - border) / scaleY; // // // Click on Point // tempP = null; // if (pointList != null) { // // look if a point was clicked // for (Point p : pointList) { // if (x >= p.getX() - recSize.getX() / 2 && y >= p.getY() - recSize.getY() / 2 // && x <= p.getX() + recSize.getX() / 2 && y <= p.getY() * scaleY + recSize.getY() / 2) { // if (e.getButton() == MouseEvent.BUTTON3) {//TODO: test // tempP = p; // deletePoint = true; // } else { // pointDrag = true; // tempP = p; // } // } // } // // New Point // if (!pointDrag && e.getButton() != MouseEvent.BUTTON3 && e.getX() != 0 // && e.getX() != this.getWidth() / scaleX) { // for (int i = 0; i < pointList.size(); i++) { // // When a point already exist on this x position // if (x == pointList.get(i).getX() || x == width || x == 0) { // break; // } // if (x < pointList.get(i).getX() && !added) { // if (e.getY() <= border) { // pointList.add(i, new Point((int) (x), 0)); // } else { // pointList.add(i, new Point((int) (x), (int) y)); // } // added = true; // pointDrag = true; // tempP = pointList.get(i); // } // } // } // // Delete a Point // if (deletePoint && tempP.getX() != 0 // && /*(*//*tempP.getX() != this.getWidth() / scaleX || */tempP != pointList.getLast())/*)*/ { // pointList.remove(tempP); // } // // repaint(); // } } /** * When a point of a Switch is pressed. * * @param e MouseEvent */ public void switchPressed(MouseEvent e) { System.out.println("switchPressed"); boolean added = false; boolean deletePoint = false; double x = (e.getX() - border) / scaleX; e.getY(); // Halbe Iterations Distanz double dist = (width / (model.getIterations() - 1)) / 2; // Click on Point tempP = null; if (pointList != null) { for (Point p : pointList) { if (x >= p.getX() - dist * 2 && x <= p.getX() + dist * 2) { if (e.getButton() == MouseEvent.BUTTON3) { tempP = p; deletePoint = true; } else { pointDrag = true; tempP = p; } } } // New Point if (!pointDrag && e.getButton() != MouseEvent.BUTTON3 && x != 0 && x != width) { for (int i = 0; i < pointList.size() && !added; i++) { if (x < pointList.get(i).getX() - dist) { // double p1, p2 um location der points zu bestimmen double p1 = pointList.get(i - 1).getX(); double p2 = pointList.get(i).getX(); // Punkte hinzufügen, je nachdem ob true oder false if (pointList.get(i - 1).getY() != (int) (height / 6) && pointList.get(i).getY() != (int) (height / 6)) { pointList.add(i, new Point((int) ((x + p2) / 2 + dist), (int) (height - height / 6))); pointList.add(i, new Point((int) ((x + p2) / 2 + dist), (int) (height / 6))); pointList.add(i, new Point((int) ((x + p1) / 2 - dist), (int) (height / 6))); pointList.add(i, new Point((int) ((x + p1) / 2 - dist), (int) (height - height / 6))); added = true; } else if (pointList.get(i - 1).getY() == (int) (height / 6) && pointList.get(i).getY() == (int) (height / 6)) { pointList.add(i, new Point((int) ((x + p2) / 2 + dist), (int) (height / 6))); pointList.add(i, new Point((int) ((x + p2) / 2 + dist), (int) (height - height / 6))); pointList.add(i, new Point((int) ((x + p1) / 2 - dist), (int) (height - height / 6))); pointList.add(i, new Point((int) ((x + p1) / 2 - dist), (int) (height / 6))); added = true; } } } } // Delete a Point if (deletePoint && tempP != pointList.getFirst() && tempP != pointList.getLast()) { int i = pointList.indexOf(tempP); // If Right, else if Left if (tempP.getY() == (int) (height / 6) && i < pointList.size() - 1 && i > 0) { pointList.remove(i); pointList.remove(i - 1); pointList.remove(i - 2); pointList.remove(i - 3); } else if (tempP.getY() == (int) (height - height / 6)) { pointList.remove(i + 2); pointList.remove(i + 1); pointList.remove(i); pointList.remove(i - 1); } } repaint(); } } @Override public void mouseReleased(MouseEvent e) { System.out.println("mouseReleased"); this.actualGraphPoints.sort(new UnitGraphPointComperator()); // if (pointDrag) { // pointDrag = false; // tempP = null; // } // /** // * reset the dragInformation. // */ // dragInformation = ""; // repaint(); } /** * When the Component is Resized. * * @param e ComponentEvent */ public void componentResized(ComponentEvent e) { System.out.println("componentResized"); calculateWidthHeight(); updateRepresentativePositions(); // Wenn ein anderes Element genommen wird /* if (init) { init = false; // for scale on the first initialisation if (width == -1 && height == -1) { width = this.getWidth() - (border * 2); height = this.getHeight() - (border * 2); } // Scale scaleX = (this.getWidth() - (border * 2)) / width; scaleY = (this.getHeight() - (border * 2)) / height; // set the scroll graph invisible this.getParent().getParent().setVisible(false); } // Scale scaleX = (this.getWidth() - (border * 2)) / width; scaleY = (this.getHeight() - (border * 2)) / height; */ repaint(); } @Override public void componentHidden(ComponentEvent e) { } @Override public void componentMoved(ComponentEvent e) { } @Override public void componentShown(ComponentEvent e) { } /** * Empty the Graph. */ public void empty() { System.out.println("empty"); pointList = null; tempElements = null; current = null; isSwitch = false; isElement = false; repaint(); } /** * Resets the Points for the Element. */ public void reset() { System.out.println("reset"); // pointList.removeAll(pointList); // if (isSwitch) { // pointList.addFirst(new Point(-border, (int) (height / 6))); // pointList.addLast(new Point((int) ((this.getWidth()) / scaleX), (int) (height / 6))); // } else { // pointList.addFirst(new Point(0, 0)); // pointList.addLast(new Point((int) ((this.getWidth() - (border * 2)) / scaleX), 0)); // } // repaint(); } /** * converts the number to fit the canvas. * * @param d the number to convert * @return the converted number */ public double convertToCanvasY(float d) { System.out.println("convertToCanvasY"); return (height - (d * (height / maximum))); } /** * converts the number to fit the value. * * @param d the number to convert * @return the converted number */ public float convertToValueY(double d) { System.out.println("convertToValueY"); return (float) Math.round(((height - (height * (d / height))) / (height / maximum)) * 10) / 10; } /** * Visualize the HolonElement on the Graph. * * @param selectedElement which should be visualized */ public void repaintWithNewElement(ArrayList selectedElement) { System.out.println("repaintWithNewElement"); // //maybe linkedlist better? // //arrayOfFloats = selectedElement.get(selectedElement.size() - 1).getAvailableEnergyPerElementAt(); // current = selectedElement.get(selectedElement.size()-1); // tempElements=selectedElement; // pointList = selectedElement.get(selectedElement.size() - 1).getGraphPoints(); // isSwitch = false; // isElement = true; // maximum = getMaximum(selectedElement.get(selectedElement.size() - 1)); // // First time clicked on the Element // if (pointList.isEmpty()) { // pointList.addFirst(new Point(0, 0)); // pointList.addLast(new Point((int) ((this.getWidth() - (border * 2)) / scaleX), 0)); // } // repaint(); } /** * Visualize the Switch on the Graph. * * @param s which should be visualized */ public void repaintWithNewSwitch(HolonSwitch s) { System.out.println("repaintWithNewSwitch"); // //arrayOfBooleans = s.getValueArray(); // current=s; // pointList = s.getGraphPoints(); // isSwitch = true; // isElement = false; // // First time clicked on the Element // if (pointList.isEmpty()) { // pointList.addFirst(new Point(-border, (int) (height / 6))); // pointList.addLast(new Point((int) ((this.getWidth()) / scaleX), (int) (height / 6))); // } // repaint(); } /** * Build a Curve for the Graph. * * @param p1 startpoint * @param p2 endpoint * @return the CubicCurve2D for the Graph */ public CubicCurve2D buildCurve(Point p1, Point p2) { System.out.println("buildCurve"); x1 = (int) p1.getX(); y1 = (int) p1.getY(); x2 = (int) p2.getX(); y2 = (int) p2.getY(); // calculate the controllpoints ctrlx1 = x1 + (x2 - x1) / 2; ctrlx2 = x2 - (x2 - x1) / 2; if (y1 < y2) { ctrly1 = y1 + (y2 - y1) / 10; ctrly2 = y2 - (y2 - y1) / 10; } else { ctrly1 = y1 - (y1 - y2) / 10; ctrly2 = y2 + (y1 - y2) / 10; } // set the curve c.setCurve(x1 * scaleX, y1 * scaleY, ctrlx1 * scaleX, ctrly1 * scaleY, ctrlx2 * scaleX, ctrly2 * scaleY, x2 * scaleX, y2 * scaleY); return c; } /** * Fills the Arrays with booleans. */ public void fillArrayofBooleans() { System.out.println("fillArrayofBooleans"); for (int i = 0; i < STANDARD_GRAPH_ACCURACY; i++) { int t = (int) getYValueAt((int) (i * width / (STANDARD_GRAPH_ACCURACY - 1))); if (t <= height / 2) { ((HolonSwitch)current).setActiveAt(i, true); } else { ((HolonSwitch)current).setActiveAt(i, false); } } } /** * Fills the Arrays of each HolonElement. */ @SuppressWarnings("unchecked") public void generateSampleCurves() { System.out.println("generateSampleCurves"); for (HolonElement he : tempElements) { maximum = getMaximum(he); he.setGraphPoints((LinkedList) pointList.clone()); //foreach(Point p: pointList) System.out.println("------------"); System.out.println("pointList["); for(Point p: pointList) { System.out.println(p); } System.out.println("]"); for (int i = 0; i < STANDARD_GRAPH_ACCURACY; i++) {//!!!!! he.setAvailableEnergyPerElementAt(i, convertToValueY(getYValueAt2((int) (i * width / (100 - 1))))); } System.out.println("TestgraphPoints:"); he.testFunctiongetAvailableEnergyAt(0); } } /** * Convert the graph widget point to a pointlist from a holon element * @param unitgraph */ public LinkedList convertUnitGraphToHolonElemntPointList(LinkedList unitgraph) { LinkedList graphpoints = new LinkedList(); if(width == 0 || height == 0) return graphpoints; for(Point p: unitgraph) { //CalcX int x = (int )((p.getX() / width)* 100.0); //CalcY int y = (int )((1.0-(p.getY() / height))* 100.0); //1.0- because 0 is at the top, width is at the bottom //AddPoint graphpoints.add(new Point(x, y)); } return graphpoints; } public LinkedList convertHolonElementPointListToUnitGraph(LinkedList graphPoints) { LinkedList unitgraph = new LinkedList(); for(Point p: graphPoints) { //CalcX int x = (int )((p.getX() / 100.0)* width); //CalcY int y = (int )((1.0-(p.getY() / 100.0))* height); //1.0- because 0 is at the top, width is at the bottom //AddPoint unitgraph.add(new Point(x, y)); } return unitgraph; } /** * Get the Y Value at the x Coordination. * * @param xVal the x value for the y value * @return y, the value at x */ public float getYValueAt(int xVal) { System.out.println("getYValueAt"); for (int i = 0; i < pointList.size() - 1; i++) { // get the Points if (xVal <= pointList.get(i + 1).getX()) { // Curve erstellen Line2D l1 = new Line2D.Double(pointList.get(i).getX(), pointList.get(i).getY(), pointList.get(i + 1).getX(), pointList.get(i + 1).getY()); Line2D l2 = new Line2D.Double(xVal, 0, xVal, height); return getIntersectionPoint(l1, l2); } } return 0; } /** * Get y value at the x Coordination via curves. * * @param xVal the x value for the y value * @return y value at x */ public float getYValueAt2(int xVal) { System.out.println("getYValueAt2"); for (int i = 0; i < pointList.size() - 1; i++) { // get the Points if (xVal >= pointList.get(i).getX()) { // Curve erstellen c = buildCurve(pointList.get(i), pointList.get(i + 1)); c.subdivide(cl, cr); // Teil der Kurve aussuchen if (cl.getX1() <= xVal * scaleX && cl.getX2() > xVal * scaleX) { c = cl; // Kurve Links von "unten" if (pointList.get(i).getY() >= pointList.get(i + 1).getY()) { for (float j = (float) (height - 1); j >= 0; j -= 0.1f) { if (c.contains(xVal * scaleX, j * scaleY)) { return (float) (j); } } } else {// Kurve Links von "oben" for (float j = 0; j < height; j += 0.1f) { if (c.contains(xVal * scaleX, j * scaleY)) { return (float) (j); } } } } else { c = cr; // Kurve Links von "unten" if (pointList.get(i).getY() >= pointList.get(i + 1).getY()) { for (float j = 0; j < height; j += 0.1f) { if (c.contains(xVal * scaleX, j * scaleY)) { return (float) (j); } } } else {// Kurve Links von "oben" for (float j = (float) (height - 1); j >= 0; j -= 0.1f) { if (c.contains(xVal * scaleX, j * scaleY)) { return (float) (j); } } } } } } // else return getYValueAt(xVal); } /** * Get the Intersection Point of 2 Lines. * * @param l1 the first Line * @param l2 the second Line * @return The Intersection Point */ public float getIntersectionPoint(Line2D l1, Line2D l2) { System.out.println("getIntersectionPoint"); if (!l1.intersectsLine(l2)) { return 0;// null; } double px = l1.getX1(), py = l1.getY1(), rx = l1.getX2() - px, ry = l1.getY2() - py; double qx = l2.getX1(), qy = l2.getY1(), sx = l2.getX2() - qx, sy = l2.getY2() - qy; double det = sx * ry - sy * rx; if (det == 0) { return 0;// null; } else { double z = (sx * (qy - py) + sy * (px - qx)) / det; if (z < 0 || z > 1) { return 0;// new Point(0, 0); // intersection at end point! } return (float) (py + z * ry);// new Point((int) (px + z * rx), (int) // (py + z * ry)); } } // end intersection line-line public void update(ArrayList obj) { System.out.println("update"); ArrayDeque queue = new ArrayDeque<>(); AbstractCpsObject u = null; queue.addAll(obj); while (!queue.isEmpty()) { u = queue.pop(); repaintGraph(u); } empty(); if (u instanceof CpsUpperNode) for (AbstractCpsObject adjacent : ((CpsUpperNode) u).getNodes()) { queue.add(adjacent); } } void repaintGraph(AbstractCpsObject u) { System.out.println("repaintGraph"); ArrayList list = new ArrayList<>(); if (u instanceof HolonObject) { for (HolonElement ele : ((HolonObject) u).getElements()) { list.add(ele); repaintWithNewElement(list); generateSampleCurves(); list.remove(0); } } else if (u instanceof HolonSwitch) { repaintWithNewSwitch((HolonSwitch) u); fillArrayofBooleans(); } } float getMaximum(HolonElement ele) { System.out.println("getMaximum"); if (ele.isFlexible()) { return ele.getFlexibleEnergyAvailablePerElement(); } else { return ele.getEnergyPerElement(); } } /** * sets the localPeriod of the Current Graph * @param localPeriod */ public void setLocalPeriod(int localPeriod){ System.out.println("setLocalPeriod"); if(isElement)for(IGraphedElement e:tempElements)e.setLocalPeriod(localPeriod); else if(isSwitch)current.setLocalPeriod(localPeriod); } /** * gets the LocalPeriod of the CurrentGraph * @return localPeriod of the current Element or Switch */ public int getLocalPeriod(){ System.out.println("getLocalPeriod"); if(current!=null)return current.getLocalPeriod(); else return model.getGraphIterations();//TODO: maybe rename } public boolean isStretching(){ System.out.println("isStretching"); return current.isStretching(); } public void setStretching(boolean b){ System.out.println("setStretching"); if(isElement)for(IGraphedElement e:tempElements)e.setStretching(b); else if(isSwitch)current.setStretching(b); } }