package org.infoobject.magicmap.visualization.layout; import edu.uci.ics.jung.graph.Edge; import edu.uci.ics.jung.graph.Graph; import edu.uci.ics.jung.graph.Vertex; import net.sf.magicmap.client.model.node.Node; import net.sf.magicmap.client.model.node.ClientNode; import net.sf.magicmap.client.model.location.jung.MagicRepulsionFunction; import org.infoobject.core.relation.domain.InformationRelationEdge; import org.infoobject.core.relation.domain.PositionRelationEdge; import org.infoobject.core.relation.domain.RelationEdge; import org.infoobject.core.relation.domain.RelationEdgeVisitor; import org.infoobject.magicmap.node.model.InformationObjectNode; import java.awt.*; import java.util.HashMap; import java.util.Map; /** * <p> * Class InformationNodeLayoutManager ZUSAMMENFASSUNG * </p> * <p> * DETAILS * </p> * * @author Jan Friderici * Date: 10.08.2008 * Time: 23:16:12 */ public class InformationNodeLayoutManager { private Graph graph; private AssociationSpringLayout layout; private LayoutThread thread; private Map<Node, PhysicalVertex> physicalVertexMap = new HashMap<Node, PhysicalVertex>(); private Map<InformationObjectNode, InformationVertex> infoVertexMap = new HashMap<InformationObjectNode, InformationVertex>(); private Map<RelationEdge, Edge> edgeMap = new HashMap<RelationEdge, Edge>(); private final Object graphMutex = new Object(); // TODO Buggy! private RelationEdgeVisitor relationAdder = new RelationEdgeVisitor() { public void visit(PositionRelationEdge relation) { thread.suspend(); try { final Node sourceNode = relation.getSourceNode(); final InformationObjectNode targetNode = relation.getTargetNode(); if (sourceNode instanceof ClientNode) { System.out.println("sourceNode = " + sourceNode); } PhysicalVertex physicalVertex = physicalVertexMap.get(sourceNode); InformationVertex infoVertex = infoVertexMap.get(targetNode); if (physicalVertex == null){ physicalVertex = addPhysicalNode(sourceNode); } if (infoVertex == null){ infoVertex = addInformtionNode(targetNode); } if (!edgeMap.containsKey(relation)){ System.out.println("physicalVertex.getGraph() = " + physicalVertex.getGraph()); System.out.println("infoVertex.getGraph() = " + infoVertex.getGraph()); RelationJungEdge edge = new RelationJungEdge(physicalVertex, infoVertex, relation); edgeMap.put(relation, edge); graph.addEdge(edge); } layout.update(); } finally { thread.unsupend(); } } public void visit(InformationRelationEdge relation) { thread.suspend(); try { final InformationObjectNode sourceNode = relation.getSourceNode(); final InformationObjectNode targetNode = relation.getTargetNode(); InformationVertex v1 = infoVertexMap.get(sourceNode); InformationVertex v2 = infoVertexMap.get(targetNode); if(v1 == null) { v1 = addInformtionNode(sourceNode); } if(v2 == null) { v2 = addInformtionNode(targetNode); } if (!edgeMap.containsKey(relation)){ RelationJungEdge edge = new RelationJungEdge(v1, v2, relation); edgeMap.put(relation, edge); graph.addEdge(edge); } layout.update(); } finally { thread.unsupend(); } } }; /** * * @param graph */ public InformationNodeLayoutManager(Graph graph) { this.graph = graph; layout = new AssociationSpringLayout(graph); layout.setRepulsionFunction(new MagicRepulsionFunction()); thread = new LayoutThread(layout); this.layout.resize(new Dimension(320, 200)); } public void suspend() { thread.suspend(); } public void unsupend() { thread.unsupend(); } public void start() { thread.start(); } public void stop() { thread.stop(); } public void removeNode(Node node) { thread.suspend(); synchronized (graphMutex) { try { Vertex vertex = node.isPhysical() ? physicalVertexMap.remove(node) : infoVertexMap.remove((InformationObjectNode)node); if (vertex != null) { this.graph.removeVertex(vertex); layout.update(); } } finally{ thread.unsupend(); } } } public void addRelation(RelationEdge edge) { System.out.println(getClass().getName() + " edge = " + edge); thread.suspend(); synchronized (graphMutex) { try { edge.accept(relationAdder); } finally{ thread.unsupend(); } } } public void move(Node node) { Vertex vertex = node.isPhysical() ? physicalVertexMap.get(node) : infoVertexMap.get(node); thread.suspend(); try { if (vertex != null) { layout.setX(vertex, node.getX()); layout.setY(vertex, node.getY()); } }finally{ thread.unsupend(); } } public void removeRelation(RelationEdge edge) { //To change body of created methods use File | Settings | File Templates. } public void resize(int width, int height) { synchronized (graphMutex) { this.layout.resize(new Dimension(width, height)); } } // Needed for layout stuff even if no edges exist! public void addNode(Node node) { thread.suspend(); try { if (node.isPhysical() && !physicalVertexMap.containsKey(node)) { addPhysicalNode(node); layout.update(); } } finally { thread.unsupend(); } } private InformationVertex addInformtionNode(InformationObjectNode targetNode) { InformationVertex infoVertex; infoVertex = new InformationVertex(targetNode); infoVertexMap.put(targetNode, infoVertex); graph.addVertex(infoVertex); return infoVertex; } private PhysicalVertex addPhysicalNode(Node sourceNode) { PhysicalVertex physicalVertex; physicalVertex = new PhysicalVertex(sourceNode); physicalVertexMap.put(sourceNode, physicalVertex); graph.addVertex(physicalVertex); layout.setFix(physicalVertex); return physicalVertex; } }