📄 defaultgraphmodel.java
字号:
edit.execute(); if (edits != null) { for (int i = 0; i < edits.length; i++) if (edits[i] instanceof GraphModelEvent.ExecutableGraphChange) ((GraphModelEvent.ExecutableGraphChange) edits[i]) .execute(); } postEdit(edit); } } } /** * Sends <code>cells</code> to back. */ public void toBack(Object[] cells) { GraphModelLayerEdit edit = createLayerEdit(cells, GraphModelLayerEdit.BACK); if (edit != null) { edit.execute(); postEdit(edit); } } /** * Brings <code>cells</code> to front. */ public void toFront(Object[] cells) { GraphModelLayerEdit edit = createLayerEdit(cells, GraphModelLayerEdit.FRONT); if (edit != null) { edit.execute(); postEdit(edit); } } protected GraphModelLayerEdit createLayerEdit(Object[] cells, int layer) { return new GraphModelLayerEdit(cells, layer); } // // Edit Creation // /** * Returns an edit that represents an insert. */ protected GraphModelEdit createInsertEdit( Object[] cells, Map attributeMap, ConnectionSet cs, ParentMap pm, UndoableEdit[] edits) { GraphModelEdit edit = createEdit(cells, null, attributeMap, cs, pm); if (edit != null) { if (edits != null) for (int i = 0; i < edits.length; i++) edit.addEdit(edits[i]); edit.end(); } return edit; } /** * Returns an edit that represents a remove. */ protected GraphModelEdit createRemoveEdit(Object[] cells) { // Remove from GraphStructure ConnectionSet cs = ConnectionSet.create(this, cells, true); // Remove from Group Structure ParentMap pm = ParentMap.create(this, cells, true, false); // Construct Edit //GraphModelEdit edit = new GraphModelEdit(cells, cs, pm); GraphModelEdit edit = createEdit(null, cells, null, cs, pm); if (edit != null) edit.end(); return edit; } /** * Returns an edit that represents a change. */ protected GraphModelEdit createCellEdit( Map attributes, ConnectionSet cs, ParentMap pm, UndoableEdit[] edits) { //GraphModelEdit edit = new GraphModelEdit(cs, propertyMap, pm); GraphModelEdit edit = createEdit(null, null, attributes, cs, pm); if (edit != null) { if (edits != null) for (int i = 0; i < edits.length; i++) edit.addEdit(edits[i]); edit.end(); } return edit; } protected GraphModelEdit createEdit( Object[] inserted, Object[] removed, Map attributes, ConnectionSet cs, ParentMap pm) { return new GraphModelEdit( inserted, removed, attributes, cs, pm); } // // Change Handling // /** * Inserts <code>cells</code> into the model. Returns * the cells that were inserted (including descendants). */ protected Object[] handleInsert(Object[] cells) { Object[] inserted = null; if (cells != null) { for (int i = 0; i < cells.length; i++) // Add to Roots if no parent if (getParent(cells[i]) == null) roots.add(cells[i]); // Return *all* inserted cells inserted = getDescendants(this, cells).toArray(); } return inserted; } /** * Removes <code>cells</code> from the model. Returns * the cells that were removed as roots. */ protected Object[] handleRemove(Object[] cells) { List removedRoots = new ArrayList(); if (cells != null) for (int i = 0; i < cells.length; i++) if (getParent(cells[i]) == null && roots.remove(cells[i])) removedRoots.add(cells[i]); return removedRoots.toArray(); } /** * Applies <code>cells</code> to the model. Returns * a parent map that may be used to undo this change. */ protected ParentMap handleParentMap(ParentMap parentMap) { if (parentMap != null) { ParentMap undo = new ParentMap(); Iterator it = parentMap.entries(); while (it.hasNext()) { ParentMap.Entry entry = (ParentMap.Entry) it.next(); Object child = entry.getChild(); Object parent = entry.getParent(); undo.addEntry(child, getParent(child)); if (parent == null){ if (child instanceof MutableTreeNode){ ((MutableTreeNode)child).removeFromParent(); } } else { if (parent instanceof DefaultMutableTreeNode && child instanceof MutableTreeNode){ ((DefaultMutableTreeNode)parent).add((MutableTreeNode)child); } } boolean isRoot = roots.contains(child); if (parent == null && !isRoot) roots.add(child); else if (parent != null && isRoot) roots.remove(child); } return undo; } return null; } /** * Applies <code>attributes</code> to the cells specified as keys. * Returns the <code>attributes</code> to undo the change. */ protected Map handleAttributes(Map attributes) { if (attributes != null) { Hashtable undo = new Hashtable(); Iterator it = attributes.entrySet().iterator(); while (it.hasNext()) { Map.Entry entry = (Map.Entry) it.next(); Object cell = entry.getKey(); Map deltaNew = (Map) entry.getValue(); //System.out.println("deltaNew="+deltaNew); //System.out.println("stateOld="+getAttributes(cell)); if (cell instanceof GraphCell){ Map deltaOld = ((GraphCell)cell).changeAttributes(deltaNew); //System.out.println("stateNew="+getAttributes(cell)); //System.out.println("deltaOld="+deltaOld); undo.put(cell, deltaOld); } else { Map attr = getAttributes(cell); if (attr != null){ Map deltaOld = GraphConstants.applyMap(deltaNew, attr); //System.out.println("stateNew="+getAttributes(cell)); //System.out.println("deltaOld="+deltaOld); undo.put(cell, deltaOld); } } } return undo; } return null; } // // Connection Set Handling // /** * Applies <code>connectionSet</code> to the model. Returns * a connection set that may be used to undo this change. */ protected ConnectionSet handleConnectionSet(ConnectionSet cs) { if (cs != null) { ConnectionSet csundo = new ConnectionSet(); Iterator it = cs.connections(); while (it.hasNext()) { ConnectionSet.Connection c = (ConnectionSet.Connection) it.next(); Object edge = c.getEdge(); if (c.isSource()) csundo.connect(edge, getSource(edge), true); else csundo.connect(edge, getTarget(edge), false); handleConnection(c); } return csundo; } return null; } /** * Inserts the specified connection into the model. */ protected void handleConnection(ConnectionSet.Connection c) { Object edge = c.getEdge(); Object old = (c.isSource()) ? getSource(edge) : getTarget(edge); Object port = c.getPort(); if (port != old) { connect(edge, old, c.isSource(), true); if (contains(port) && contains(edge)) connect(edge, port, c.isSource(), false); } } /** * Connects or disconnects the edge and port in this model * based on <code>remove</code>. Subclassers should override * this to update connectivity datastructures. */ protected void connect( Object edge, Object port, boolean isSource, boolean remove) { if (port instanceof Port) if (remove) ((Port) port).removeEdge(edge); else ((Port) port).addEdge(edge); if (remove) port = null; if (edge instanceof Edge) { if (isSource) ((Edge) edge).setSource(port); else ((Edge) edge).setTarget(port); } } // // GraphModelListeners // /** * Adds a listener for the GraphModelEvent posted after the graph changes. * * @see #removeGraphModelListener * @param l the listener to add */ public void addGraphModelListener(GraphModelListener l) { listenerList.add(GraphModelListener.class, l); } /** * Removes a listener previously added with <B>addGraphModelListener()</B>. * * @see #addGraphModelListener * @param l the listener to remove */ public void removeGraphModelListener(GraphModelListener l) { listenerList.remove(GraphModelListener.class, l); } /* * Notify all listeners that have registered interest for * notification on this event type. The event instance * is lazily created using the parameters passed into * the fire method. * @see EventListenerList */ protected void fireGraphChanged( Object source, GraphModelEvent.GraphModelChange edit) { // Guaranteed to return a non-null array Object[] listeners = listenerList.getListenerList(); GraphModelEvent e = null; // Process the listeners last to first, notifying // those that are interested in this event for (int i = listeners.length - 2; i >= 0; i -= 2) { if (listeners[i] == GraphModelListener.class) { // Lazily create the event: if (e == null) e = new GraphModelEvent(source, edit); ((GraphModelListener) listeners[i + 1]).graphChanged(e); } } } /** * Return an array of all GraphModelListeners that were added to this model. */ public GraphModelListener[] getGraphModelListeners() { return (GraphModelListener[]) listenerList.getListeners( GraphModelListener.class); } // // GraphModelEdit // /** * An implementation of GraphModelChange that can be added to the model * event. */ public class GraphModelEdit extends CompoundEdit implements GraphModelEvent.GraphModelChange, GraphModelEvent.ExecutableGraphChange { /* Cells that were inserted/removed/changed during the last execution. */ protected Object[] insert, changed, remove, context; /* Cells that were inserted/removed/changed during the last execution. */ protected Object[] inserted, removed; /* Property map for the next execution. Attribute Map is passed to the views on inserts. */ protected Map attributes, previousAttributes; /* Parent map for the next execution. */ protected ParentMap parentMap, previousParentMap; /* ConnectionSet for the next execution. */ protected ConnectionSet connectionSet, previousConnectionSet; /* Piggybacked undo from the views. */ protected Map cellViews = new Hashtable(); /** * Constructs an edit record. * * @param e the element * @param index the index into the model >= 0 * @param removed a set of elements that were removed * @param inserted a set of roots that were inserted */ public GraphModelEdit( Object[] inserted, Object[] removed, Map attributes, ConnectionSet connectionSet, ParentMap parentMap) { super(); this.insert = inserted; this.remove = removed; this.connectionSet = connectionSet; this.attributes = attributes; this.parentMap = parentMap; previousAttributes = attributes; previousConnectionSet = connectionSet; previousParentMap = parentMap; // Remove Empty Parents if (parentMap != null) { // Compute Empty Group Map childCount = new Hashtable(); Iterator it = parentMap.entries(); while (it.hasNext()) { ParentMap.Entry entry = (ParentMap.Entry) it.next(); Object child = entry.getChild(); if (!isPort(child)) { Object oldParent = getParent(child); Object newParent = entry.getParent(); if (oldParent != newParent) { changeChildCount(childCount, oldParent, -1); changeChildCount(childCount, newParent, 1); } } } handleEmptyGroups(filterParents(childCount, 0)); } } public Object[] filterParents(Map childCount, int children) { ArrayList list = new ArrayList(); Iterator it = childCount.entrySet().iterator(); while (it.hasNext()) { Map.Entry entry = (Map.Entry) it.next(); if (entry.getValue() instanceof Integer) { if (((Integer) entry.getValue()).intValue() == children) list.add(entry.getKey()); } } return list.toArray(); } protected void changeChildCount(Map childCount, Object parent, int change) { if (parent != null) { Integer count = (Integer) childCount.get(parent); if (count == null) { count = new Integer(getChildCount(parent)); } int newValue = count.intValue() + change; childCount.put(parent, new Integer(newValue)); } } /** * Adds the groups that become empty to the cells that * will be removed. (Auto remove empty cells.) Removed * cells will be re-inserted on undo, and the parent- * child relations will be restored.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -