annotate java/src/uk/ac/qmul/eecs/ccmi/gui/Diagram.java @ 8:ea7885bd9bff tip

fixed bug : render solid line as dotted/dashed when moving the stylus from dotted/dashed to solid
author ccmi-guest
date Thu, 03 Jul 2014 16:12:20 +0100
parents 9e67171477bc
children
rev   line source
fiore@0 1 /*
fiore@0 2 CCmI Editor - A Collaborative Cross-Modal Diagram Editing Tool
fiore@0 3
fiore@0 4 Copyright (C) 2011 Queen Mary University of London (http://ccmi.eecs.qmul.ac.uk/)
fiore@0 5
fiore@0 6 This program is free software: you can redistribute it and/or modify
fiore@0 7 it under the terms of the GNU General Public License as published by
fiore@0 8 the Free Software Foundation, either version 3 of the License, or
fiore@0 9 (at your option) any later version.
fiore@0 10
fiore@0 11 This program is distributed in the hope that it will be useful,
fiore@0 12 but WITHOUT ANY WARRANTY; without even the implied warranty of
fiore@0 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
fiore@0 14 GNU General Public License for more details.
fiore@0 15
fiore@0 16 You should have received a copy of the GNU General Public License
fiore@0 17 along with this program. If not, see <http://www.gnu.org/licenses/>.
fiore@0 18 */
fiore@0 19 package uk.ac.qmul.eecs.ccmi.gui;
fiore@0 20
fiore@0 21 import java.awt.geom.Point2D;
fiore@0 22 import java.util.Set;
fiore@0 23
fiore@0 24 import uk.ac.qmul.eecs.ccmi.diagrammodel.CollectionModel;
fiore@0 25 import uk.ac.qmul.eecs.ccmi.diagrammodel.DiagramElement;
fiore@0 26 import uk.ac.qmul.eecs.ccmi.diagrammodel.DiagramModel;
fiore@3 27 import uk.ac.qmul.eecs.ccmi.diagrammodel.DiagramTreeNode;
fiore@0 28 import uk.ac.qmul.eecs.ccmi.diagrammodel.NodeProperties;
fiore@0 29 import uk.ac.qmul.eecs.ccmi.diagrammodel.TreeModel;
fiore@0 30 import uk.ac.qmul.eecs.ccmi.gui.persistence.PrototypePersistenceDelegate;
fiore@3 31 import uk.ac.qmul.eecs.ccmi.network.AwarenessMessage;
fiore@3 32 import uk.ac.qmul.eecs.ccmi.network.DiagramEventActionSource;
fiore@0 33
fiore@0 34 /**
fiore@3 35 * The {@code Diagram} class holds all the data needed for a representation of the diagram. It is used by component classes
fiore@0 36 * such as {@link GraphPanel} and {@link DiagramTree} to draw the diagram by accessing the diagram model or by
fiore@0 37 * {@link EditorTabbedPane} to assign a title to the tabs out of the diagram name.
fiore@0 38 *
fiore@0 39 */
fiore@0 40 public abstract class Diagram implements Cloneable {
fiore@0 41
fiore@3 42 /**
fiore@3 43 * Crates a new instance of a Diagram. The diagram created through this method is not shared with any peer via
fiore@3 44 * a server.
fiore@3 45 * @param name the name of the diagram.
fiore@3 46 * @param nodes an array of node prototypes. Nodes inserted by users in the diagram will be created by cloning these nodes.
fiore@3 47 * @param edges an array of edge prototypes. Edges inserted by users in the diagram will be created by cloning these edges.
fiore@3 48 * @param prototypePersistenceDelegate a delegate class to handle nodes and edges persistence.
fiore@3 49 * @return a new instance of {@code Diagram}
fiore@3 50 */
fiore@0 51 public static Diagram newInstance(String name, Node[] nodes, Edge[] edges, PrototypePersistenceDelegate prototypePersistenceDelegate){
fiore@0 52 return new LocalDiagram(name,nodes,edges,prototypePersistenceDelegate);
fiore@0 53 }
fiore@0 54
fiore@3 55 /**
fiore@3 56 * Returns the name of the diagram. The name identifies the diagram uniquely in the editor. There cannot
fiore@3 57 * be two diagrams with the same name open at the same time. This makes things easier when sharing diagrams
fiore@3 58 * with other users via the network.
fiore@3 59 *
fiore@3 60 * @return the name of the diagram
fiore@3 61 */
fiore@0 62 public abstract String getName();
fiore@0 63
fiore@3 64 /**
fiore@3 65 * Assign this diagram a new name.
fiore@3 66 * @param name the new name of the diagram
fiore@3 67 */
fiore@0 68 public abstract void setName(String name);
fiore@0 69
fiore@3 70 /**
fiore@3 71 * Returns an array with the node prototypes. Node prototypes are used when creating new node
fiore@3 72 * instances via the {@code clone()} method.
fiore@3 73 *
fiore@3 74 * @return an array of nodes
fiore@3 75 */
fiore@0 76 public abstract Node[] getNodePrototypes();
fiore@0 77
fiore@3 78 /**
fiore@3 79 * Returns an array with the edge prototypes. Edge prototypes are used when creating new edge
fiore@3 80 * instances via the {@code clone()} method.
fiore@3 81 *
fiore@3 82 * @return an array of edges
fiore@3 83 */
fiore@0 84 public abstract Edge[] getEdgePrototypes();
fiore@0 85
fiore@3 86 /**
fiore@3 87 * Returns the tree model of this diagram. Note that each diagram holds a {@code DiagramModel}
fiore@3 88 * which has two sub-models ({@code TreeModel} and {@code CollectionModel}). Changes on one
fiore@3 89 * sub-model will affect the other model as well.
fiore@3 90 *
fiore@3 91 * @return the tree model of this diagram
fiore@3 92 *
fiore@3 93 * @see uk.ac.qmul.eecs.ccmi.diagrammodel.DiagramModel uk.ac.qmul.eecs.ccmi.diagrammodel.DiagramModel
fiore@3 94 */
fiore@0 95 public abstract TreeModel<Node,Edge> getTreeModel();
fiore@0 96
fiore@3 97 /**
fiore@3 98 * Returns the collection model of this diagram. Note that each diagram holds a {@code DiagramModel}
fiore@3 99 * which has two sub-models ({@code TreeModel} and {@code CollectionModel}). Changes on one
fiore@3 100 * sub-model will affect the other model as well.
fiore@3 101 *
fiore@3 102 * @return the tree model of this diagram
fiore@3 103 *
fiore@3 104 * @see uk.ac.qmul.eecs.ccmi.diagrammodel.DiagramModel uk.ac.qmul.eecs.ccmi.diagrammodel.DiagramModel
fiore@3 105 */
fiore@0 106 public abstract CollectionModel<Node,Edge> getCollectionModel();
fiore@0 107
fiore@3 108 /**
fiore@3 109 * Returns the model updater of this diagram. The model updater is the delegate for all the
fiore@3 110 * update operations affecting the diagram model.
fiore@3 111 *
fiore@3 112 * @return the model updater for this diagram
fiore@3 113 */
fiore@0 114 public abstract DiagramModelUpdater getModelUpdater();
fiore@0 115
fiore@3 116 /**
fiore@3 117 * Returns the label of the diagram. The label is slightly different from the name as it's the string
fiore@3 118 * appearing in the tabbed pane of the editor. It includes asterisk character at the end when the {@code DiagramModel}
fiore@3 119 * of this class has been changed and not yet saved on hard disk.
fiore@3 120 *
fiore@3 121 * @return a label for this diagram
fiore@3 122 */
fiore@0 123 public abstract String getLabel();
fiore@0 124
fiore@3 125 /**
fiore@3 126 * Returns the delegates for this diagram for nodes and edges prototypes persistence.
fiore@3 127 * When saving a diagram to an xml file each node and edge of the prototypes is encoded
fiore@3 128 * in the xml file. Indeed the template of a diagram is made of of its prototypes.
fiore@3 129 * In the template is held the general attributes common to all the nodes and edges, like
fiore@3 130 * for instance the type of a node but not its current position.
fiore@3 131 *
fiore@3 132 * @return the PrototypePersistenceDelegate for this diagram
fiore@3 133 */
fiore@0 134 public abstract PrototypePersistenceDelegate getPrototypePersistenceDelegate();
fiore@0 135
fiore@0 136 @Override
fiore@0 137 public Object clone(){
fiore@0 138 try {
fiore@0 139 return super.clone();
fiore@0 140 } catch (CloneNotSupportedException e) {
fiore@0 141 throw new RuntimeException(e);
fiore@0 142 }
fiore@0 143 }
fiore@0 144
fiore@0 145 private static class LocalDiagram extends Diagram {
fiore@0 146
fiore@0 147 private LocalDiagram(String name, Node[] nodes, Edge[] edges,PrototypePersistenceDelegate prototypePersistenceDelegate){
fiore@0 148 this.name = name;
fiore@0 149 this.nodes = nodes;
fiore@0 150 this.edges = edges;
fiore@0 151 this.prototypePersistenceDelegate = prototypePersistenceDelegate;
fiore@0 152 diagramModel = new DiagramModel<Node,Edge>(nodes,edges);
fiore@0 153 innerModelUpdater = new InnerModelUpdater();
fiore@0 154 }
fiore@0 155
fiore@0 156 @Override
fiore@0 157 public String getName(){
fiore@0 158 return name;
fiore@0 159 }
fiore@0 160
fiore@0 161 @Override
fiore@0 162 public void setName(String name){
fiore@0 163 this.name = name;
fiore@0 164 }
fiore@0 165
fiore@0 166 @Override
fiore@0 167 public Node[] getNodePrototypes(){
fiore@0 168 return nodes;
fiore@0 169 }
fiore@0 170
fiore@0 171 @Override
fiore@0 172 public Edge[] getEdgePrototypes(){
fiore@0 173 return edges;
fiore@0 174 }
fiore@0 175
fiore@0 176 @Override
fiore@0 177 public TreeModel<Node,Edge> getTreeModel(){
fiore@0 178 return diagramModel.getTreeModel();
fiore@0 179 }
fiore@0 180
fiore@0 181 @Override
fiore@0 182 public CollectionModel<Node,Edge> getCollectionModel(){
fiore@0 183 return diagramModel.getDiagramCollection();
fiore@0 184 }
fiore@0 185
fiore@0 186 @Override
fiore@0 187 public String getLabel(){
fiore@0 188 return name;
fiore@0 189 }
fiore@0 190
fiore@0 191 @Override
fiore@0 192 public DiagramModelUpdater getModelUpdater(){
fiore@0 193 return innerModelUpdater;
fiore@0 194 }
fiore@0 195
fiore@0 196 @Override
fiore@0 197 public String toString(){
fiore@0 198 return name;
fiore@0 199 }
fiore@0 200
fiore@0 201 @Override
fiore@0 202 public PrototypePersistenceDelegate getPrototypePersistenceDelegate(){
fiore@0 203 return prototypePersistenceDelegate;
fiore@0 204 }
fiore@0 205
fiore@3 206 /**
fiore@3 207 * Creates a new {@code Diagram} by clonation.
fiore@3 208 */
fiore@0 209 @Override
fiore@0 210 public Object clone(){
fiore@0 211 LocalDiagram clone = (LocalDiagram)super.clone();
fiore@0 212 clone.name = getName();
fiore@0 213 clone.nodes = getNodePrototypes();
fiore@0 214 clone.edges = getEdgePrototypes();
fiore@0 215 /* constructor with no args makes just a dummy wrapper */
fiore@0 216 clone.diagramModel = new DiagramModel<Node,Edge>(nodes,edges);
fiore@0 217 clone.innerModelUpdater = clone.new InnerModelUpdater();
fiore@0 218 return clone;
fiore@0 219 }
fiore@0 220
fiore@0 221 private DiagramModel<Node,Edge> diagramModel;
fiore@0 222 private InnerModelUpdater innerModelUpdater;
fiore@0 223 private PrototypePersistenceDelegate prototypePersistenceDelegate;
fiore@0 224 private String name;
fiore@0 225 private Node[] nodes;
fiore@0 226 private Edge[] edges;
fiore@0 227
fiore@0 228 private class InnerModelUpdater implements DiagramModelUpdater {
fiore@0 229
fiore@0 230 @Override
fiore@3 231 public boolean getLock(DiagramTreeNode treeNode, Lock lock, DiagramEventActionSource source) {
fiore@0 232 /* using a non shared diagram requires no actual lock, therefore the answer is always yes */
fiore@0 233 return true;
fiore@0 234 }
fiore@0 235
fiore@0 236 @Override
fiore@3 237 public void yieldLock(DiagramTreeNode treeNode, Lock lock, DiagramEventActionSource actionSource) {}
fiore@0 238
fiore@3 239 @Override
fiore@3 240 public void sendAwarenessMessage(AwarenessMessage.Name awMsgName, Object source){}
fiore@3 241
fiore@0 242 @Override
fiore@3 243 public void insertInCollection(DiagramElement element,DiagramEventSource source) {
fiore@0 244 if(element instanceof Node)
fiore@3 245 diagramModel.getDiagramCollection().insert((Node)element,source);
fiore@0 246 else
fiore@3 247 diagramModel.getDiagramCollection().insert((Edge)element,source);
fiore@0 248 }
fiore@0 249
fiore@0 250 @Override
fiore@0 251 public void insertInTree(DiagramElement element) {
fiore@0 252 if(element instanceof Node)
fiore@3 253 diagramModel.getTreeModel().insertTreeNode((Node)element,DiagramEventSource.TREE);
fiore@0 254 else
fiore@3 255 diagramModel.getTreeModel().insertTreeNode((Edge)element,DiagramEventSource.TREE);
fiore@0 256 }
fiore@0 257
fiore@0 258 @Override
fiore@3 259 public void takeOutFromCollection(DiagramElement element, DiagramEventSource source) {
fiore@3 260 diagramModel.getDiagramCollection().takeOut(element,source);
fiore@0 261 }
fiore@0 262
fiore@0 263 @Override
fiore@0 264 public void takeOutFromTree(DiagramElement element) {
fiore@3 265 diagramModel.getTreeModel().takeTreeNodeOut(element,DiagramEventSource.TREE);
fiore@0 266 }
fiore@0 267
fiore@0 268 @Override
fiore@3 269 public void setName(DiagramElement element, String name,DiagramEventSource source) {
fiore@3 270 element.setName(name,source);
fiore@0 271 }
fiore@0 272
fiore@0 273 @Override
fiore@3 274 public void setNotes(DiagramTreeNode treeNode, String notes,DiagramEventSource source) {
fiore@3 275 diagramModel.getTreeModel().setNotes(treeNode, notes,source);
fiore@0 276 }
fiore@0 277
fiore@0 278 @Override
fiore@0 279 public void setProperty(Node node, String type, int index,
fiore@3 280 String value,DiagramEventSource source) {
fiore@3 281 node.setProperty(type, index, value,source);
fiore@0 282 }
fiore@0 283
fiore@0 284 @Override
fiore@3 285 public void setProperties(Node node, NodeProperties properties,DiagramEventSource source) {
fiore@3 286 node.setProperties(properties,source);
fiore@0 287 }
fiore@0 288
fiore@0 289 @Override
fiore@3 290 public void clearProperties(Node node,DiagramEventSource source) {
fiore@3 291 node.clearProperties(source);
fiore@0 292 }
fiore@0 293
fiore@0 294 @Override
fiore@3 295 public void addProperty(Node node, String type, String value,DiagramEventSource source) {
fiore@3 296 node.addProperty(type, value,source);
fiore@0 297 }
fiore@0 298
fiore@0 299 @Override
fiore@3 300 public void removeProperty(Node node, String type, int index,DiagramEventSource source) {
fiore@3 301 node.removeProperty(type, index,source);
fiore@0 302 }
fiore@0 303
fiore@0 304 @Override
fiore@0 305 public void setModifiers(Node node, String type, int index,
fiore@3 306 Set<Integer> modifiers,DiagramEventSource source) {
fiore@3 307 node.setModifierIndexes(type, index, modifiers,source);
fiore@0 308 }
fiore@0 309
fiore@0 310 @Override
fiore@3 311 public void setEndLabel(Edge edge, Node node, String label,DiagramEventSource source) {
fiore@3 312 edge.setEndLabel(node, label,source);
fiore@0 313 }
fiore@0 314
fiore@0 315 @Override
fiore@0 316 public void setEndDescription(Edge edge, Node node,
fiore@3 317 int index,DiagramEventSource source) {
fiore@3 318 edge.setEndDescription(node, index,source);
fiore@0 319 }
fiore@0 320
fiore@0 321 @Override
fiore@3 322 public void translate(GraphElement ge, Point2D p, double x, double y,DiagramEventSource source) {
fiore@3 323 ge.translate(p, x, y,source);
fiore@0 324 }
fiore@0 325
fiore@0 326 @Override
fiore@3 327 public void startMove(GraphElement ge, Point2D p,DiagramEventSource source) {
fiore@3 328 ge.startMove(p,source);
fiore@0 329 }
fiore@0 330
fiore@0 331 @Override
fiore@3 332 public void bend(Edge edge, Point2D p,DiagramEventSource source) {
fiore@3 333 edge.bend(p,source);
fiore@0 334 }
fiore@0 335
fiore@0 336 @Override
fiore@3 337 public void stopMove(GraphElement ge,DiagramEventSource source) {
fiore@3 338 ge.stopMove(source);
fiore@0 339 }
fiore@0 340 }
fiore@0 341 }
fiore@0 342
fiore@0 343 }