001: package org.cougaar.core.qos.frame.visualizer;
002:
003: import java.awt.Graphics2D;
004: import java.awt.geom.Point2D;
005: import java.awt.geom.RectangularShape;
006: import java.util.ArrayList;
007: import java.util.Collection;
008: import java.util.HashMap;
009: import java.util.HashSet;
010: import java.util.Iterator;
011:
012: import org.cougaar.core.qos.frame.visualizer.layout.ShapeLayout;
013: import org.cougaar.core.qos.frame.visualizer.test.FramePredicate;
014: import org.cougaar.core.qos.frame.visualizer.util.SlotChangeListener;
015:
016: /**
017: * Created by IntelliJ IDEA.
018: * User: mwalczak
019: * Date: Apr 4, 2005
020: * Time: 9:42:49 AM
021: * To change this template use File | Settings | File Templates.
022: */
023: public class ShapeContainer extends ShapeGraphic {
024: protected HashSet children;
025: protected HashMap prototypes;//, insertContainers;
026: protected HashSet frameChildren;
027: protected ShapeLayout shapeLayout;
028:
029: //private transient Logger log = Logging.getLogger(getClass().getName());
030:
031: public ShapeContainer() {
032: this ("", "");
033: }
034:
035: public boolean isContainer() {
036: return true;
037: }
038:
039: public ShapeContainer(String id, String label) {
040: super (id, label);
041: children = new HashSet();
042: frameChildren = new HashSet();
043: prototypes = new HashMap();
044: //insertContainers = new HashMap();
045: }
046:
047: public void reshape(double tx, double ty, double w, double h) {
048: super .reshape(tx, ty, w, h);
049: layoutChildren();
050: }
051:
052: public void setLayout(ShapeLayout layout) {
053: shapeLayout = layout;
054: if (shapeLayout != null) {
055: //shapeLayout.setContainer(this);
056: layoutChildren();
057: }
058: }
059:
060: public ShapeLayout getLayout() {
061: return shapeLayout;
062: }
063:
064: public void setMargins(double left, double right, double bottom,
065: double top, double hpadding, double vpadding) {
066: if (shapeLayout != null) {
067: shapeLayout.setMargins(left, right, bottom, top, hpadding,
068: vpadding);
069: layoutChildren();
070: }
071: }
072:
073: public ShapeGraphic find(double mx, double my) {
074: if (!contains(mx, my))
075: return null;
076: ShapeGraphic sh, result;
077: for (Iterator ii = children.iterator(); ii.hasNext();) {
078: sh = (ShapeGraphic) ii.next();
079: result = sh.find(mx, my);
080: if (result != null)
081: return result;
082: }
083: return this ;
084: }
085:
086: public ShapeGraphic find(org.cougaar.core.qos.frame.Frame f) {
087: if (f != null) {
088: if (frame != null && f == frame)
089: //if (frame != null && id != null && id.equals((String) f.getValue("name")))
090: return this ;
091: ShapeGraphic sh, result;
092: for (Iterator ii = children.iterator(); ii.hasNext();) {
093: sh = (ShapeGraphic) ii.next();
094: result = sh.find(f);
095: if (result != null)
096: return result;
097: }
098: }
099: return null;
100: }
101:
102: protected void layoutChildren() {
103: if (shapeLayout != null)
104: shapeLayout.doLayout(this );
105: }
106:
107: public Point2D.Double getNextInsertPosition() {
108: return new Point2D.Double(x + (width / 2d), y + (height / 2d)); //???
109: }
110:
111: public void draw(Graphics2D g2) {
112: super .draw(g2);
113: if (children.size() > 0)
114: drawChildren(g2);
115: }
116:
117: public void drawLabel(Graphics2D g2) {
118: super .drawLabel(g2);
119: if (children.size() > 0)
120: drawChildrenLabels(g2);
121: }
122:
123: protected void drawChildren(Graphics2D g2) {
124: ShapeGraphic sh;
125: for (Iterator ii = children.iterator(); ii.hasNext();) {
126: sh = (ShapeGraphic) ii.next();
127: sh.draw(g2);
128: }
129: }
130:
131: protected void drawChildrenLabels(Graphics2D g2) {
132: ShapeGraphic sh;
133: // drawing the label used to be in the sh.draw() call but
134: // moved it here so that the labels don't get drawn over
135: // by the shape of the next item
136: for (Iterator ii = children.iterator(); ii.hasNext();) {
137: sh = (ShapeGraphic) ii.next();
138: sh.drawLabel(g2);
139: }
140: }
141:
142: public boolean hasPrototype(String kind) {
143: return (prototypes.get(kind) != null);
144: }
145:
146: public Collection getPrototypes() {
147: return prototypes.values();
148: }
149:
150: public boolean hasChild(ShapeGraphic g) {
151: return children.contains(g);
152: /*
153: ShapeGraphic sh;
154: for (Iterator ii=children.iterator(); ii.hasNext();) {
155: sh=(ShapeGraphic) ii.next();
156: if (sh == g)
157: return true;
158: }
159: return false;*/
160: }
161:
162: public void add(ShapeGraphic sh) {
163: if (log.isDebugEnabled())
164: log.debug("====>" + id + ".add(ShapeGraphic): adding "
165: + sh);
166: sh.setParent(this );
167: if (sh.isPrototype())
168: prototypes.put(sh.getFramePredicate().getKind(), sh);
169: else {
170: if (!hasChild(sh)) {
171: children.add(sh);
172: if (sh.frame != null
173: && !frameChildren.contains(sh.frame))
174: frameChildren.add(sh.frame);
175: layoutChildren();
176: }
177: }
178: if (frameModel != null)
179: frameModel.fireContainerAddedChild(this , sh);
180: }
181:
182: public void add(org.cougaar.core.qos.frame.Frame frame) {
183: String kind = frame.getKind();
184: ShapeGraphic shg;
185: FramePredicate fp;
186:
187: //if (log.isDebugEnabled())
188: // log.debug("====>maybe-add: "+toString()+"\n\t adding frame(kind="+kind+", name="+frame.getValue("name")+")");
189:
190: String frameName = (String) frame.getValue("name");
191: if (frameChildren.contains(frame)) {
192: if (log.isDebugEnabled())
193: log
194: .debug("====>rejected: already have a child with name "
195: + frameName);
196: return;
197: }
198:
199: boolean foundPrototypeMatch = false;
200: for (Iterator ii = prototypes.values().iterator(); ii.hasNext();) {
201: shg = (ShapeGraphic) ii.next();
202: fp = shg.getFramePredicate();
203: if (fp != null && frame.isa(fp.getKind())) {
204: // if (log.isDebugEnabled())
205: // log.debug("****>add: "+id+"\n\t adding clone (kind="+kind+", name="+frame.getValue("name")+")");
206: add(shg.createInstance(frame, frameModel));
207: foundPrototypeMatch = true;
208: //frameChildren.add(frame);
209: }
210: }
211: if (!foundPrototypeMatch && log.isDebugEnabled())
212: log.debug("****>add: " + toString()
213: + "\n\t did not find a prototype match for kind="
214: + kind + ", discarding");
215: }
216:
217: public void remove(ShapeGraphic sh) {
218: children.remove(sh);
219: sh.setParent(null);
220: if (sh.frame != null)
221: frameChildren.remove(sh.frame);
222: layoutChildren();
223: if (frameModel != null)
224: frameModel.fireContainerRemovedChild(this , sh);
225: }
226:
227: public void remove(String shapeId) {
228: ShapeGraphic sh = null;
229: for (Iterator ii = children.iterator(); ii.hasNext();) {
230: sh = (ShapeGraphic) ii.next();
231: if (sh.getId().equals(shapeId))
232: break;
233: sh = null;
234: }
235: if (sh != null)
236: remove(sh);
237: }
238:
239: public Collection getChildren() {
240: return children;
241: }
242:
243: public int getNumChildren() {
244: return (children != null ? children.size() : 0);
245: }
246:
247: protected void buildChildren(FrameModel frameModel) {
248: // this can be either a container with no associated frame (used for grouping)
249: // of a container with a frame and a frame predicate
250: //FramePredicate fp = getFramePredicate();
251: org.cougaar.core.qos.frame.Frame f = getFrame();
252:
253: ShapeGraphic shg;
254: Collection frames;
255: org.cougaar.core.qos.frame.Frame fr;
256: for (Iterator ii = prototypes.values().iterator(); ii.hasNext();) {
257: shg = (ShapeGraphic) ii.next();
258: FramePredicate pfp = shg.getFramePredicate();
259: if (log.isDebugEnabled())
260: log.debug("'" + id + "' looking for children of type '"
261: + pfp.getKind() + "' relation='"
262: + pfp.getParentRelationship() + "' hasFrame="
263: + (f != null) + "\n");
264:
265: // if this, or one of the ShapeContainer parents has a frame, find all children of that frame - otherwise use the
266: // FramePredicate and try to find the appropriate frame
267: frames = (f != null ? this .frameModel.getAllChildren(f, pfp
268: .getParentRelationship()) : this .frameModel
269: .findFrames(pfp));
270: if (frames != null && frames.size() > 0) {
271: for (Iterator jj = frames.iterator(); jj.hasNext();) {
272: fr = (org.cougaar.core.qos.frame.Frame) jj.next();
273: if (frameModel.getGraphic(fr) == null
274: && !frameChildren.contains(frame))
275: add(fr);
276: }
277: }
278: }
279: }
280:
281: public void update(FrameModel frameModel, HashSet addedDataFrames,
282: HashSet removedDataFrames, HashSet addedRelations) {
283: //public void setFrameHelper(FrameModel frameModel) {
284: if (this .frameModel == null)
285: super .update(frameModel, addedDataFrames,
286: removedDataFrames, addedRelations);
287: if (log.isDebugEnabled())
288: log.debug("ShapeContainer(" + id + ".update:");
289:
290: buildChildren(frameModel);
291: ShapeGraphic ch;
292: for (Iterator ii = children.iterator(); ii.hasNext();) {
293: ch = (ShapeGraphic) ii.next();
294: ch.update(frameModel, addedDataFrames, removedDataFrames,
295: addedRelations);
296: }
297: }
298:
299: // clone thyself and assign the given frame
300: // make a deep copy
301: public ShapeGraphic createInstance(
302: org.cougaar.core.qos.frame.Frame frame, FrameModel fmodel) {
303: try {
304: ShapeContainer cloned = (ShapeContainer) this .clone();
305: cloned.frameModel = fmodel;
306: if (frame != null)
307: cloned.setFrame(frame);
308: cloned.setPrototype(false);
309: cloned.shapePrototype = (shapePrototype != null ? ((RectangularShape) shapePrototype
310: .clone())
311: : null);
312: cloned.shape = cloned.createShape();
313: org.cougaar.core.qos.frame.Frame parent = getFrame();
314: if (cloned.predicate != null && parent != null)
315: cloned.predicate = new FramePredicate(cloned.predicate,
316: (String) parent.getValue("name"));
317:
318: cloned.frameChildren = new HashSet();
319: cloned.shapeLayout = (shapeLayout != null ? shapeLayout
320: .cloneSelf() : null);
321: cloned.children = new HashSet();
322:
323: // clone children
324: ShapeGraphic child, clonedChild;
325: for (Iterator ii = children.iterator(); ii.hasNext();) {
326: child = (ShapeGraphic) ii.next();
327: clonedChild = child.createInstance(child.frame, fmodel);
328: clonedChild.setParent(cloned);
329: cloned.children.add(clonedChild);
330: }
331: cloned.layoutChildren();
332: cloned.prototypes = new HashMap();
333: // clone prototypes
334: String key;
335: for (Iterator ii = prototypes.keySet().iterator(); ii
336: .hasNext();) {
337: key = (String) ii.next();
338: child = (ShapeGraphic) prototypes.get(key);
339: clonedChild = child.createInstance(child.frame, fmodel);
340: clonedChild.setPrototype(true);
341: clonedChild.setParent(cloned);
342: cloned.prototypes.put(key, clonedChild);
343: }
344:
345: // clone slot change listeners
346: if (slotListeners.size() > 0) {
347: cloned.slotListeners = new ArrayList();
348: for (Iterator ii = slotListeners.iterator(); ii
349: .hasNext();) {
350: cloned.addSlotListener(((SlotChangeListener) ii
351: .next()).cloneInstance());
352: }
353: }
354: cloned.validateListeners();
355: return cloned;
356: } catch (CloneNotSupportedException ee) {
357: ee.printStackTrace();
358: }
359: return null;
360: }
361:
362: }
|