package ui.controller; import classes.AbstractCanvasObject; import classes.Edge; import classes.Node; import classes.GroupNode; import classes.Position; import classes.IntermediateCalculationCable; import ui.model.Model; import java.awt.*; import java.util.ArrayList; import java.util.Iterator; import java.util.LinkedList; class NodeController { private Model model; private CanvasController cvs; private MultiPurposeController mpC; private Point point; NodeController(Model model, CanvasController cvs, MultiPurposeController mpC) { this.model = model; this.cvs = cvs; this.mpC = mpC; } /** * Add a CpsUpperNode into Canvas */ void doUpperNode(String nodeName, GroupNode upperNode, ArrayList toGroup) { GroupNode node = new GroupNode(nodeName); node.setPosition(calculatePos(toGroup)); makeAdjacent(node, upperNode, toGroup); makeNodeOfNodes(node, upperNode, toGroup); if (upperNode == null) cvs.addNewObject(node); else addObjectInUpperNode(node, upperNode, false); } /** * Delete a CpsUpperNode from the Canvas */ void undoUpperNode(GroupNode node, GroupNode upperNode) { if(node.getNodes().size() == 0) { cvs.deleteObjectOnCanvas(node); return; } Position old = calculatePos(node.getNodes()); Position p = node.getPosition(); point = new Point(old.x - p.x, old.y - p.y); unmakeNodesOfNodes(node, upperNode); if (upperNode == null) cvs.deleteObjectOnCanvas(node); else deleteObjectInUpperNode(node, upperNode); } /** * Put selected Nodes inside the Upper Node */ private void makeNodeOfNodes(GroupNode node, GroupNode upperNode, ArrayList toGroup) { ArrayList nodes = node.getNodes(); // Put all selected Nodes into the Upper Node for (AbstractCanvasObject obj : toGroup) { // füge Neue Objecte in Neuen Node hinzu addObjectInUpperNode(obj, node, false); } for (AbstractCanvasObject abs : toGroup) { if (upperNode == null) removeForNodeOfNode(abs, null); else removeForNodeOfNode(abs, upperNode); } } /** * Transfer all relevant data from Node into the next higher layer of Node * (upperNode) */ private void unmakeNodesOfNodes(GroupNode node, GroupNode upperNode) { // add all nodes into upperNode for (Edge edge : node.getConnections()) { if (edge.getA().equals(node)) edge.getB().getConnections().remove(edge); if (edge.getB().equals(node)) edge.getA().getConnections().remove(edge); } for (AbstractCanvasObject obj : node.getNodes()) { updatePosition(obj, upperNode); if (upperNode == null) obj.setSav("CVS"); else obj.setSav("" + upperNode.getId()); } (upperNode == null ? model.getObjectsOnCanvas() : upperNode.getNodes()).addAll(node.getNodes()); // change the indices accordingly the higher layer mpC.adjustIdx(mpC.getHighestIdx((upperNode == null ? model.getCvsObjIdx() : upperNode.getNodesIdx())), node.getNodesIdx()); // add all indices of nodes into upperNode (upperNode == null ? model.getCvsObjIdx() : upperNode.getNodesIdx()).putAll(node.getNodesIdx()); } /** * Look for adjacent Nodes connected with the new CpsUpperNode and make * Connections */ private void makeAdjacent(GroupNode node, GroupNode upperNode, ArrayList toGroup) { ArrayList adj = new ArrayList<>(); ArrayList maxCapacity = new ArrayList<>(); } /** * Just checking if an Egde already exists */ boolean lookforDuplicates(AbstractCanvasObject a, AbstractCanvasObject b, ArrayList list) { for (Edge cpsEdge : list) { if ((a.equals(cpsEdge.getA()) && b.equals(cpsEdge.getB())) || (b.equals(cpsEdge.getA()) && a.equals(cpsEdge.getB()))) return true; } return false; } /** * Calculate new Position of the Upper Node */ Position calculatePos(ArrayList toGroup) { Position pos = new Position(0, 0); // sum(x0 .. xn) / numOfPos, y analog for (AbstractCanvasObject abs : toGroup) { pos.x += abs.getPosition().x; pos.y += abs.getPosition().y; } pos.x /= toGroup.size(); pos.y /= toGroup.size(); return pos; } /** * Removes the Given Obj from current Layer and adjusts the idx */ private void removeForNodeOfNode(AbstractCanvasObject obj, GroupNode upperNode) { mpC.decIdx(obj.getId(), (upperNode == null ? model.getCvsObjIdx() : upperNode.getNodesIdx())); (upperNode == null ? model.getCvsObjIdx() : upperNode.getNodesIdx()).remove(obj.getId()); (upperNode == null ? model.getObjectsOnCanvas() : upperNode.getNodes()).remove(obj); } /** * Search Lost Nodes by Backtracking by looking for edges * * @param object * actual object which we are looking at * @param find * one part of the Edge * @param lost * other part of the Edge * @return boolean if found */ private boolean backtrackLostChild(AbstractCanvasObject object, AbstractCanvasObject find, AbstractCanvasObject lost) { //if not instance of CpsUpperNode if (!(object instanceof GroupNode)) { //forEach connection look if lost and found inside for (Edge edge : object.getConnections()) { if (edge.getA().equals(find) && edge.getB().equals(lost) || edge.getA().equals(lost) && edge.getB().equals(find)) return true; } return false; } else { //if instance of Uppernode Call again for (AbstractCanvasObject cps : ((GroupNode) object).getNodes()) { if (backtrackLostChild(cps, find, lost)) return true; } return false; } } /** * Adds object to the upperNode, might replace objects if replace==true * @param object * @param upperNode * @param replace */ void addObjectInUpperNode(AbstractCanvasObject object, GroupNode upperNode, boolean replace) { if(object == null){ new Error("object == null while adding to "+upperNode.toString()).printStackTrace(); return; } if(upperNode == null){ new Error("upperNode == null while adding "+object.toString()).printStackTrace(); return; } object.setSav("" + upperNode.getId()); upperNode.getNodesIdx().put(object.getId(), upperNode.getNodes().size()); upperNode.getNodes().add(object); /** * check if we should drag & drop replace */ if(replace && !(object instanceof Node) ){ /** x of the dragged Object */ int x = object.getPosition().x; /** y of the dragged Object */ int y = object.getPosition().y; /** distance threshold for replacement */ int treshhold = model.getScale()/2; /** number of Objects that might be replaced (should be 1) */ int replaceCounter = 0; /** last object that could be replaced */ AbstractCanvasObject toBeReplaced = null; /** for each cps on Canvas */ for (AbstractCanvasObject cps : upperNode.getNodes()){ /** same object -> ignore */ if(cps == object)continue; /** x of object that might get replaced */ int c_x = cps.getPosition().x; /** y of object that might get replaced */ int c_y = cps.getPosition().y; /** if near enough */ if(Math.abs(x-c_x) edgesToDelete = new LinkedList(); for (Edge p : model.getEdgesOnCanvas()) { if(p.isConnectedTo(object)) { edgesToDelete.add(p); System.out.println("Remove Edge!"); } } model.getEdgesOnCanvas().removeAll(edgesToDelete); mpC.decIdx(object.getId(), upperNode.getNodesIdx()); upperNode.getNodesIdx().remove(object.getId()); upperNode.getNodes().remove(object); } /** * Replaces {@code toBePlaced} by {@code by} in {@code upperNode} * @param toBeReplaced * @param by * @param upperNode */ public void replaceObjectInUpperNode(AbstractCanvasObject toBeReplaced, AbstractCanvasObject by, GroupNode upperNode) { /** let all edges of 'toBeReplaced' connect to 'by' */ for(Edge e: toBeReplaced.getConnections()){ if(e.getA() == toBeReplaced){ e.setA(by); }else if(e.getB() == toBeReplaced){ e.setB(by); } /** if edge from an object to itself -> remove it */ if(e.getA() == e.getB()) ;//TODO Delte me if not nessesary else/** else add edge to 'by' */ by.addConnection(e); } /** delete 'toBeReplaced' new empty connections, to prevent Nullpointer*/ toBeReplaced.setConnections(new ArrayList(1)); /** * set Position of by to exactly toBeReplaced */ by.setPosition(toBeReplaced.getPosition()); deleteObjectInUpperNode(toBeReplaced, upperNode); } /** * If Position is out of boundaries adjust it */ private void updatePosition(AbstractCanvasObject temp, GroupNode upperNode) { int x = temp.getPosition().x - point.x; int y = temp.getPosition().y - point.y; if (y < 0) y = 0 + model.getScaleDiv2() + 1; if (upperNode != null) { if (x < upperNode.getLeftBorder() + model.getScaleDiv2() + 1) x = upperNode.getLeftBorder() + model.getScaleDiv2() + 1; } else if (x < 0) x = 0 + model.getScaleDiv2() + 1; if (x > model.getCanvasX()) x = model.getCanvasX() - model.getScaleDiv2() - 1; if (y > model.getCanvasX()) y = model.getCanvasY() - model.getScaleDiv2() - 1; temp.setPosition(new Position(x, y)); } }