001: /*
002: * $Id: JGraphpadGraphModel.java,v 1.1.1.1 2005/08/04 11:21:58 gaudenz Exp $
003: * Copyright (c) 2001-2005, Gaudenz Alder
004: *
005: * All rights reserved.
006: *
007: * See LICENSE file for license details. If you are unable to locate
008: * this file please contact info (at) jgraph (dot) com.
009: */
010: package com.jgraph.pad.graph;
011:
012: import java.awt.Component;
013: import java.util.Hashtable;
014: import java.util.Iterator;
015: import java.util.List;
016: import java.util.Map;
017:
018: import org.jgraph.graph.AttributeMap;
019: import org.jgraph.graph.ConnectionSet;
020: import org.jgraph.graph.DefaultGraphModel;
021:
022: /**
023: * GraphModel that supports cloning of {@link JGraphpadBusinessObject} and
024: * handles custom entries in nested maps to add/change/remove properties for
025: * business object (using the model's insert and edit methods).
026: */
027: public class JGraphpadGraphModel extends DefaultGraphModel {
028:
029: /**
030: * Defines the EMPTY_VALUE constant to be used in nested maps in order to
031: * remove properties from business objects.
032: */
033: public static final Object VALUE_EMPTY = new Object();
034:
035: /**
036: * Constructs a new empty graph model.
037: */
038: public JGraphpadGraphModel() {
039: super ();
040: }
041:
042: /**
043: * Constructs a new graph model using the specified root cells and
044: * attributes (for the model) and establishes the connections defined in the
045: * specified connection set between the cells.
046: *
047: * @param roots
048: * The roots to be inserted into the model.
049: * @param attributes
050: * The model's attributes.
051: * @param cs
052: * The connections to be established.
053: */
054: public JGraphpadGraphModel(List roots, AttributeMap attributes,
055: ConnectionSet cs) {
056: super (roots, attributes, cs);
057: }
058:
059: /**
060: * Extends the parent implementation to support cloning of
061: * {@link JGraphpadBusinessObject}.
062: *
063: * @param userObject
064: * The user object to be cloned.
065: * @return Returns the cloned user object.
066: */
067: protected Object cloneUserObject(Object userObject) {
068: if (userObject instanceof JGraphpadBusinessObject)
069: return ((JGraphpadBusinessObject) userObject).clone();
070: return super .cloneUserObject(userObject);
071: }
072:
073: /**
074: * Extends the parent implementation to support changing the value on
075: * {@link JGraphpadBusinessObject}. This implementation supports setting
076: * the value to String, {@link JGraphpadRichTextValue} or Map. If the new
077: * value is a map the complete properties of the user object are replaced
078: * with the specified map.
079: *
080: * @param cell
081: * The cell to change the value for.
082: * @param newValue
083: * The new value to use for the cell.
084: * @return Returns the old value of the cell.
085: */
086: public Object valueForCellChanged(Object cell, Object newValue) {
087: Object userObject = getValue(cell);
088: if (userObject instanceof JGraphpadBusinessObject) {
089: JGraphpadBusinessObject businessObject = (JGraphpadBusinessObject) userObject;
090: if (newValue instanceof String
091: || newValue instanceof JGraphpadRichTextValue
092: || newValue instanceof Component) {
093: Object oldValue = businessObject.getValue();
094: businessObject.setValue(newValue);
095: return oldValue; // exit
096: } else if (newValue instanceof Map) {
097: Map oldProperties = businessObject.getProperties();
098: businessObject.setProperties((Map) newValue);
099: return oldProperties; // exit
100: }
101: }
102: return super .valueForCellChanged(cell, newValue);
103: }
104:
105: /**
106: * Extends the parent implementation to support changing properties on
107: * {@link JGraphpadBusinessObject} by adding a map for the business object
108: * to the nested map which is passed to an insert or edit call. The special
109: * {@link #VALUE_EMPTY} is used to remove a property from a business object.
110: *
111: * @param attributes
112: * The attributes to be processed.
113: * @return Returns the attributes used to undo the change.
114: */
115: protected Map handleAttributes(Map attributes) {
116: Map undo = super .handleAttributes(attributes);
117: if (attributes != null) {
118:
119: // Creates the undo map if the superclass returned null
120: if (undo == null)
121: undo = new Hashtable();
122:
123: // Iterates through all entries in the nested map
124: Iterator it = attributes.entrySet().iterator();
125: while (it.hasNext()) {
126: Map.Entry entry = (Map.Entry) it.next();
127: Object cell = entry.getKey();
128: Map properties = (Map) entry.getValue();
129:
130: // If the key is a business object then we have to take
131: // the properties and apply them to the business object.
132: if (cell instanceof JGraphpadBusinessObject) {
133: JGraphpadBusinessObject bo = (JGraphpadBusinessObject) cell;
134: Map deltaOld = new Hashtable();
135: Iterator it2 = properties.entrySet().iterator();
136: while (it2.hasNext()) {
137: Map.Entry property = (Map.Entry) it2.next();
138: Object key = property.getKey();
139: Object value = property.getValue();
140:
141: // Handles the special VALUE_EMPTY to remove the
142: // respective value from the properties.
143: Object oldValue = (value == VALUE_EMPTY) ? bo
144: .getProperties().remove(key) : bo
145: .putProperty(key, value);
146:
147: // Uses the special VALUE_EMPTY in the undo
148: // datastructure if the there was no property for
149: // the specified key.
150: if (oldValue != null)
151: deltaOld.put(key, oldValue);
152: else
153: deltaOld.put(key, VALUE_EMPTY);
154: }
155: undo.put(cell, deltaOld);
156: }
157: }
158: }
159: return undo;
160: }
161:
162: }
|