001: /*
002: * @(#)GraphModel.java 1.0 03-JUL-04
003: *
004: * Copyright (c) 2001-2004 Gaudenz Alder
005: *
006: */
007: package org.jgraph.graph;
008:
009: import java.util.Iterator;
010: import java.util.Map;
011:
012: import javax.swing.event.UndoableEditListener;
013: import javax.swing.undo.UndoableEdit;
014:
015: import org.jgraph.event.GraphModelListener;
016:
017: /**
018: * The interface that defines a suitable data model for a JGraph.
019: *
020: * @version 1.0 1/1/02
021: * @author Gaudenz Alder
022: */
023:
024: public interface GraphModel {
025:
026: //
027: // Roots
028: //
029:
030: /**
031: * Returns the number of roots in the model. Returns 0 if the model is
032: * empty.
033: *
034: * @return the number of roots in the model
035: */
036: int getRootCount();
037:
038: /**
039: * Returns the root at index <I>index </I> in the model. This should not
040: * return null if <i>index </i> is a valid index for the model (that is
041: * <i>index </i>>= 0 && <i>index </i>< getRootCount()).
042: *
043: * @return the root of at index <I>index </I>
044: */
045: Object getRootAt(int index);
046:
047: /**
048: * Returns the index of <code>root</code> in the model. If root is
049: * <code>null</code>, returns -1.
050: *
051: * @param root
052: * a root in the model, obtained from this data source
053: * @return the index of the root in the model, or -1 if the parent is
054: * <code>null</code>
055: */
056: int getIndexOfRoot(Object root);
057:
058: /**
059: * Returns <code>true</code> if <code>node</code> or one of its
060: * ancestors is in the model.
061: *
062: * @return <code>true</code> if <code>node</code> is in the model
063: */
064: boolean contains(Object node);
065:
066: /**
067: * Returns a <code>AttributeMap</code> that represents the properties for
068: * the specified cell.
069: *
070: * @return properties of <code>node</code> as a <code>Map</code>
071: */
072: AttributeMap getAttributes(Object node);
073:
074: /**
075: * Returns the user object for the specified cell.
076: *
077: * @return userobject of <code>node</code>
078: */
079: Object getValue(Object node);
080:
081: //
082: // Graph Structure
083: //
084:
085: /**
086: * Returns the source of <code>edge</code>. <I>edge </I> must be an
087: * object previously obtained from this data source.
088: *
089: * @return <code>Object</code> that represents the source of <i>edge </i>
090: */
091: Object getSource(Object edge);
092:
093: /**
094: * Returns the target of <code>edge</code>. <I>edge </I> must be an
095: * object previously obtained from this data source.
096: *
097: * @return <code>Object</code> that represents the target of <i>edge </i>
098: */
099: Object getTarget(Object edge);
100:
101: /**
102: * Returns <code>true</code> if <code>port</code> is a valid source for
103: * <code>edge</code>. <I>edge </I> and <I>port </I> must be objects
104: * previously obtained from this data source.
105: *
106: * @return <code>true</code> if <code>port</code> is a valid source for
107: * <code>edge</code>.
108: */
109: boolean acceptsSource(Object edge, Object port);
110:
111: /**
112: * Returns <code>true</code> if <code>port</code> is a valid target for
113: * <code>edge</code>. <I>edge </I> and <I>port </I> must be objects
114: * previously obtained from this data source.
115: *
116: * @return <code>true</code> if <code>port</code> is a valid target for
117: * <code>edge</code>.
118: */
119: boolean acceptsTarget(Object edge, Object port);
120:
121: /**
122: * Returns an iterator of the edges connected to <code>port</code>.
123: * <I>port </I> must be a object previously obtained from this data source.
124: * This method never returns null.
125: *
126: * @param port
127: * a port in the graph, obtained from this data source
128: * @return <code>Iterator</code> that represents the connected edges
129: */
130: Iterator edges(Object port);
131:
132: /**
133: * Returns <code>true</code> if <code>edge</code> is a valid edge.
134: *
135: * @return <code>true</code> if <code>edge</code> is a valid edge.
136: */
137: boolean isEdge(Object edge);
138:
139: /**
140: * Returns <code>true</code> if <code>port</code> is a valid port,
141: * possibly supporting edge connection.
142: *
143: * @return <code>true</code> if <code>port</code> is a valid port.
144: */
145: boolean isPort(Object port);
146:
147: //
148: // Group structure
149: //
150:
151: /**
152: * Returns the parent of <I>child </I> in the model. <I>child </I> must be a
153: * node previously obtained from this data source. This returns null if
154: * <i>child </i> is a root in the model.
155: *
156: * @param child
157: * a node in the graph, obtained from this data source
158: * @return the parent of <I>child </I>
159: */
160: Object getParent(Object child);
161:
162: /**
163: * Returns the index of child in parent. If either the parent or child is
164: * <code>null</code>, returns -1.
165: *
166: * @param parent
167: * a note in the tree, obtained from this data source
168: * @param child
169: * the node we are interested in
170: * @return the index of the child in the parent, or -1 if either the parent
171: * or the child is <code>null</code>
172: */
173: int getIndexOfChild(Object parent, Object child);
174:
175: /**
176: * Returns the child of <I>parent </I> at index <I>index </I> in the
177: * parent's child array. <I>parent </I> must be a node previously obtained
178: * from this data source. This should not return null if <i>index </i> is a
179: * valid index for <i>parent </i> (that is <i>index </i>>= 0 && <i>index
180: * </i>< getChildCount( <i>parent </i>)).
181: *
182: * @param parent
183: * a node in the tree, obtained from this data source
184: * @return the child of <I>parent </I> at index <I>index </I>
185: */
186: Object getChild(Object parent, int index);
187:
188: /**
189: * Returns the number of children of <I>parent </I>. Returns 0 if the node
190: * is a leaf or if it has no children. <I>parent </I> must be a node
191: * previously obtained from this data source.
192: *
193: * @param parent
194: * a node in the tree, obtained from this data source
195: * @return the number of children of the node <I>parent </I>
196: */
197: int getChildCount(Object parent);
198:
199: /**
200: * Returns whether the specified node is a leaf node. The way the test is
201: * performed depends on the <code>askAllowsChildren</code> setting.
202: *
203: * @param node
204: * the node to check
205: * @return true if the node is a leaf node
206: */
207: boolean isLeaf(Object node);
208:
209: //
210: // Change Support
211: //
212:
213: /**
214: * Inserts the <code>cells</code> and connections into the model, and
215: * passes <code>attributes</code> to the views. Notifies the model- and
216: * undo listeners of the change.
217: */
218: void insert(Object[] roots, Map attributes, ConnectionSet cs,
219: ParentMap pm, UndoableEdit[] e);
220:
221: /**
222: * Removes <code>cells</code> from the model. If
223: * <code>removeChildren</code> is <code>true</code>, the children are
224: * also removed. Notifies the model- and undo listeners of the change.
225: */
226: void remove(Object[] roots);
227:
228: /**
229: * Applies the <code>propertyMap</code> and the connection changes to the
230: * model. The initial <code>edits</code> that triggered the call are
231: * considered to be part of this transaction. Notifies the model- and undo
232: * listeners of the change. <strong>Note: </strong> If only
233: * <code>edits</code> is non-null, the edits are directly passed to the
234: * UndoableEditListeners.
235: */
236: void edit(Map attributes, ConnectionSet cs, ParentMap pm,
237: UndoableEdit[] e);
238:
239: /**
240: * Indicates the start of one level of an executable change
241: */
242: public void beginUpdate();
243:
244: /**
245: * Indicates the end of the current level of an executable change
246: */
247: public void endUpdate();
248:
249: /**
250: * Executes the specified executable change on this graph model
251: * @param change the change to be executed
252: */
253: public void execute(ExecutableChange change);
254:
255: /**
256: * Returns a map of (cell, clone)-pairs for all <code>cells</code> and
257: * their children. Special care should be taken to replace references
258: * between cells.
259: */
260: Map cloneCells(Object[] cells);
261:
262: /**
263: * Messaged when the value of the cell has changed, eg from within the edit
264: * method.
265: */
266: Object valueForCellChanged(Object cell, Object newValue);
267:
268: //
269: // Layering
270: //
271:
272: /**
273: * Sends <code>cells</code> to back.
274: */
275: void toBack(Object[] cells);
276:
277: /**
278: * Brings <code>cells</code> to front.
279: */
280: void toFront(Object[] cells);
281:
282: //
283: // Listeners
284: //
285:
286: /**
287: * Adds a listener for the GraphModelEvent posted after the model changes.
288: */
289: void addGraphModelListener(GraphModelListener l);
290:
291: /**
292: * Removes a listener previously added with <B>addGraphModelListener() </B>.
293: */
294: void removeGraphModelListener(GraphModelListener l);
295:
296: /**
297: * Adds an undo listener for notification of any changes. Undo/Redo
298: * operations performed on the <code>UndoableEdit</code> will cause the
299: * appropriate ModelEvent to be fired to keep the view(s) in sync with the
300: * model.
301: */
302: void addUndoableEditListener(UndoableEditListener listener);
303:
304: /**
305: * Removes an undo listener.
306: */
307: void removeUndoableEditListener(UndoableEditListener listener);
308:
309: }
|