001: /*
002: * The contents of this file are subject to the terms of the Common Development
003: * and Distribution License (the License). You may not use this file except in
004: * compliance with the License.
005: *
006: * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
007: * or http://www.netbeans.org/cddl.txt.
008: *
009: * When distributing Covered Code, include this CDDL Header Notice in each file
010: * and include the License file at http://www.netbeans.org/cddl.txt.
011: * If applicable, add the following below the CDDL Header, with the fields
012: * enclosed by brackets [] replaced by your own identifying information:
013: * "Portions Copyrighted [year] [name of copyright owner]"
014: *
015: * The Original Software is NetBeans. The Initial Developer of the Original
016: * Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun
017: * Microsystems, Inc. All Rights Reserved.
018: */
019:
020: package org.netbeans.modules.soa.mapper.basicmapper.canvas.jgo;
021:
022: import com.nwoods.jgo.JGoRectangle;
023: import java.awt.Color;
024: import java.awt.Point;
025: import java.awt.Rectangle;
026: import java.beans.PropertyChangeEvent;
027: import java.beans.PropertyChangeListener;
028: import java.util.List;
029: import java.util.logging.Logger;
030:
031: import javax.swing.Icon;
032: import javax.swing.ImageIcon;
033:
034: import com.nwoods.jgo.JGoArea;
035: import com.nwoods.jgo.JGoListPosition;
036: import com.nwoods.jgo.JGoObject;
037: import com.nwoods.jgo.JGoPort;
038: import com.nwoods.jgo.JGoSelection;
039: import org.netbeans.modules.soa.mapper.basicmapper.canvas.jgo.util.AccessibleArea;
040: import org.netbeans.modules.soa.mapper.basicmapper.canvas.jgo.util.GradientRectangle;
041: import org.netbeans.modules.soa.mapper.common.basicmapper.canvas.gtk.ICanvasFieldNode;
042: import org.netbeans.modules.soa.mapper.common.basicmapper.methoid.IFieldNode;
043: import org.netbeans.modules.soa.mapper.common.basicmapper.methoid.IMethoidNode;
044: import org.netbeans.modules.soa.mapper.common.IMapperGroupNode;
045: import org.netbeans.modules.soa.mapper.common.IMapperNode;
046: import org.netbeans.modules.soa.mapper.common.gtk.ICanvasNode;
047:
048: /**
049: * <p>
050: *
051: * Title: </p> BasicCanvasMethoidNode<p>
052: *
053: * Description: </p> BasicCanvasMethoidNode provides a basic implementation of a
054: * methoid canvas node. <p>
055: *
056: * Copyright: Copyright (c) 2002 </p> <p>
057: *
058: * Company: </p>
059: *
060: * @author Un Seng Leong
061: * @created December 4, 2002
062: * @version 1.0
063: */
064: public class BasicCanvasMethoidNode extends AbstractCanvasMethoidNode {
065:
066: /**
067: * the log instance
068: */
069: private Logger mLogger = Logger
070: .getLogger(BasicCanvasMethoidNode.class.getName());
071:
072: /**
073: * the border rectange
074: */
075: private JGoRectangle mBorderRect;
076:
077: /**
078: * the height of this canvas node
079: */
080: private int mFixedHeight;
081:
082: /**
083: * the width of this canvas node
084: */
085: private int mFixedWidth;
086:
087: /**
088: * the title bar ui component of this node.
089: */
090: private BasicTitleBarUI mTitleBar;
091:
092: /**
093: * Creates a new BasicCanvasMethoidNode object.
094: *
095: * @param node the method node
096: */
097: public BasicCanvasMethoidNode(IMethoidNode node) {
098: super (node);
099: mTitleBar = new BasicTitleBarUI(node.getMethoidName(),
100: ((ImageIcon) node.getIcon()).getImage());
101: mTitleBar.setSelectable(false);
102: mTitleBar.setDraggable(false);
103: mTitleBar.setResizable(false);
104: mTitleBar.setSelectable(false);
105: mTitleBar.resizeToMinimum();
106:
107: this .addObjectAtTail(mTitleBar);
108: this .setSelectable(true);
109: this .setDraggable(true);
110: this .setResizable(false);
111: this .setSelectable(true);
112: this .setPickableBackground(true);
113:
114: mBorderRect = new GradientRectangle(this );
115: mBorderRect.setSelectable(false);
116: mBorderRect.setDraggable(false);
117: mBorderRect.setResizable(false);
118:
119: this .addObjectAtHead(mBorderRect);
120:
121: super .expand();
122:
123: node.addPropertyChangeListener(new MethoidPropertyListener());
124: }
125:
126: /**
127: * Return ture if the point is within the expand or collapse button, false
128: * otherwise.
129: *
130: * @param point the point to check
131: * @return ture if the point is within the expand or collapse button,
132: * false otherwise.
133: */
134: public boolean isInButton(Point point) {
135: return this .mTitleBar.isInButton(point);
136: }
137:
138: /**
139: * Add a canvas node
140: *
141: * @param node the node to be added
142: */
143: public void addNode(ICanvasNode node) {
144: super .addNode(node);
145: configNewChild(node);
146: }
147:
148: /**
149: * Insert a chid node to this container with the specified index
150: *
151: * @param node the node to be added
152: * @param index the index to add the node
153: */
154: public void insertNode(ICanvasNode node, int index) {
155: super .insertNode(node, index);
156: configNewChild(node);
157: }
158:
159: /**
160: * Return the collapse canvas node of this node.
161: *
162: * @return the collapse canvas node of this node.
163: */
164: public ICanvasNode collapse() {
165: super .collapse();
166: layoutChildren();
167: changeAreaSize();
168: mTitleBar.collapse();
169: return this ;
170: }
171:
172: /**
173: * Return the expand canvas node of this node.
174: *
175: * @return the expand canvas node of this node.
176: */
177: public ICanvasNode expand() {
178: super .expand();
179: layoutChildren();
180: changeAreaSize();
181: mTitleBar.expand();
182: return this ;
183: }
184:
185: /**
186: * Remove a node from this methoid.
187: *
188: * @param node a node from this methoid
189: */
190: public void removeNode(ICanvasNode node) {
191: super .removeNode(node);
192:
193: if (node instanceof JGoObject) {
194: this .removeObject((JGoObject) node);
195: }
196:
197: if (node instanceof ICanvasFieldNode) {
198: ICanvasFieldNode canvasFieldNode = (ICanvasFieldNode) node;
199: canvasFieldNode.getFieldNode().setGroupNode(null);
200:
201: Object port = canvasFieldNode.getConnectPointObject();
202: if (port instanceof JGoObject) {
203: this .removeObject((JGoObject) port);
204: }
205: }
206: }
207:
208: /**
209: * Invoks when size or location change of this canvas.
210: *
211: * @param prevRect the pervious rectangle.
212: */
213: protected void geometryChange(java.awt.Rectangle prevRect) {
214: // see if this is just a move and not a scale
215: if ((prevRect.width == getWidth())
216: && (prevRect.height == getHeight())) {
217: // let the default JGoArea implementation do the work
218: super .geometryChange(prevRect);
219: } else {
220: ensureBounding();
221: }
222:
223: updatePortBounds();
224: }
225:
226: // Update the port positions, which will in-turn change
227: // the bounding rect of the methoid itself.
228: private void updatePortBounds() {
229: JGoListPosition pos = getFirstObjectPos();
230: while (pos != null) {
231: JGoObject obj = getObjectAtPos(pos);
232: pos = getNextObjectPos(pos);
233:
234: if (obj instanceof AccessibleArea) {
235: if (((AccessibleArea) obj).isBoundingRectInvalid()) {
236: continue;
237: }
238: }
239:
240: if (obj instanceof BasicCanvasFieldNode) {
241: ((BasicCanvasFieldNode) obj).layoutPorts();
242: }
243: }
244: }
245:
246: /**
247: * layout the children of this canvas node.
248: */
249: protected void layoutChildren() {
250: List nodeList = this .getModifiableNodeList();
251: int i = 0;
252: JGoObject prevNode = mTitleBar;
253: JGoObject node = null;
254:
255: synchronized (nodeList) {
256: for (; i < nodeList.size(); i++) {
257: node = (JGoObject) nodeList.get(i);
258:
259: if (isExpanded()) {
260: node.setSpotLocation(JGoObject.TopLeft, prevNode,
261: JGoObject.BottomLeft);
262: node.setLocation(node.getLeft(), node.getTop() + 1);
263: node.setVisible(true);
264: } else {
265: node.setSpotLocation(JGoObject.TopLeft, prevNode,
266: JGoObject.TopLeft);
267: node.setVisible(false);
268: }
269:
270: if (node instanceof BasicCanvasFieldNode) {
271: BasicCanvasFieldNode fieldNode = (BasicCanvasFieldNode) node;
272: JGoPort port = (JGoPort) fieldNode
273: .getConnectPointObject();
274: port.setSpotLocation(JGoObject.TopLeft, node,
275: JGoObject.TopLeft);
276: }
277:
278: prevNode = node;
279: }
280: }
281: }
282:
283: /**
284: * Invokes when the size of this area change.
285: */
286: public void changeAreaSize() {
287:
288: if (isExpanded()) {
289: setBoundingRect(getLeft(), getTop(), mFixedWidth,
290: mFixedHeight * (getModifiableNodeList().size() + 1));
291: } else {
292: setBoundingRect(getLeft(), getTop(), mFixedWidth,
293: mFixedHeight);
294: }
295:
296: Rectangle rect = computeBoundingRectWithoutPorts();
297: mBorderRect.setBoundingRect(rect.x, rect.y, rect.width,
298: rect.height);
299: }
300:
301: // A version of computeBoundingRect that does not include the ports.
302: // This is useful for when we want to obtain a bounding rect that
303: // represents only the visible methoid itself - i.e. this is used
304: // when creating the selection rect for a methoid.
305: public Rectangle computeBoundingRectWithoutPorts() {
306: Rectangle rect = null;
307: JGoListPosition pos = getFirstObjectPos();
308: while (pos != null) {
309: JGoObject obj = getObjectAtPos(pos);
310: pos = getNextObjectPos(pos);
311:
312: if (obj instanceof AccessibleArea) {
313: if (((AccessibleArea) obj).isBoundingRectInvalid()) {
314: continue;
315: }
316: if (rect == null) {
317: Rectangle b = obj.getBoundingRect();
318: rect = new Rectangle(b.x, b.y, b.width, b.height);
319: } else {
320: // add the object's bounding rect to this one
321: rect.add(obj.getBoundingRect());
322: }
323: }
324: }
325: return rect;
326: }
327:
328: /**
329: * Ensure the children are within this canvas node and the canvas node is
330: * big enough to holds all the children.
331: */
332: public void ensureBounding() {
333: List nodeList = this .getModifiableNodeList();
334: int i = 0;
335:
336: int fixedWidth = mTitleBar.getWidth();
337: int fixedHeight = mTitleBar.getHeight();
338:
339: JGoObject node = null;
340:
341: synchronized (nodeList) {
342: for (; i < nodeList.size(); i++) {
343: node = (JGoObject) nodeList.get(i);
344:
345: fixedWidth = Math.max(fixedWidth, node.getWidth());
346: fixedHeight = Math.max(fixedHeight, node.getHeight());
347: }
348: }
349: boolean isFixedSizeChanged = fixedWidth != mFixedWidth
350: || fixedHeight != mFixedHeight;
351: if (isFixedSizeChanged) {
352: mFixedWidth = fixedWidth;
353: mFixedHeight = fixedHeight;
354: mTitleBar.setSize(mFixedWidth, mFixedHeight);
355:
356: for (i = 0; i < nodeList.size(); i++) {
357: node = (JGoObject) nodeList.get(i);
358: node.setSize(mFixedWidth, mFixedHeight);
359: }
360:
361: layoutChildren();
362: changeAreaSize();
363: }
364: }
365:
366: /**
367: * Description of the Method
368: *
369: * @param node Description of the Parameter
370: */
371: private void configNewChild(ICanvasNode node) {
372: if (node instanceof JGoObject) {
373:
374: JGoObject jgoNode = (JGoObject) node;
375: jgoNode.setSelectable(false);
376: jgoNode.setDraggable(false);
377: jgoNode.setResizable(false);
378: jgoNode.setVisible(false);
379:
380: if (jgoNode instanceof JGoArea) {
381: ((JGoArea) jgoNode).setSelectable(false);
382: }
383:
384: this .addObjectAtTail(jgoNode);
385:
386: JGoPort port = null;
387: if (node instanceof ICanvasFieldNode) {
388: ICanvasFieldNode canvasFieldNode = (ICanvasFieldNode) node;
389: canvasFieldNode.setContainer(this );
390: port = (JGoPort) canvasFieldNode
391: .getConnectPointObject();
392: port.setVisible(false);
393: bringObjectToFront(port);
394: }
395:
396: if (jgoNode.getWidth() > mFixedWidth
397: || jgoNode.getHeight() > mFixedHeight) {
398: ensureBounding();
399: } else {
400: jgoNode.setBoundingRect(mTitleBar.getBoundingRect());
401: layoutChildren();
402: changeAreaSize();
403: }
404: }
405: }
406:
407: /**
408: * Provides listener listens on the node change on the methoid node that
409: * this class repersents.
410: *
411: * @author sleong
412: * @created January 27, 2003
413: */
414: private class MethoidPropertyListener implements
415: PropertyChangeListener {
416: /**
417: * Add or remove the canvas node coorsponding to the new / remove node
418: * of the methoid node that this canvas node repersents.
419: *
420: * @param e the PropertyChangeEvent value
421: */
422: public void propertyChange(PropertyChangeEvent e) {
423: if (e.getPropertyName().equals(
424: IMapperGroupNode.NODE_INSERTED)) {
425: int i = 0;
426: for (IMapperNode findNode = getMethoidNode()
427: .getFirstNode(); findNode != null; findNode = getMethoidNode()
428: .getNextNode(findNode)) {
429:
430: if (findNode == e.getNewValue()) {
431: ICanvasFieldNode newChild = ((BasicCanvasView) BasicCanvasMethoidNode.this
432: .getCanvas()).getCanvasObjectFactory()
433: .createFieldNode(
434: (IFieldNode) e.getNewValue());
435: insertNode(newChild, i);
436: break;
437: }
438: i++;
439: }
440: } else if (e.getPropertyName().equals(
441: IMapperGroupNode.NODE_REMOVED)) {
442: List nodeList = getModifiableNodeList();
443: synchronized (nodeList) {
444: for (int i = 0; i < nodeList.size(); i++) {
445: ICanvasFieldNode node = (ICanvasFieldNode) nodeList
446: .get(i);
447: if (node.getFieldNode() == e.getOldValue()) {
448: removeNode(node);
449: break;
450: }
451: }
452: }
453: } else if (e.getPropertyName().equals(
454: IMethoidNode.NAME_CHANGED)) {
455: BasicCanvasMethoidNode.this .setName(mMethoidNode
456: .getMethoidName());
457: } else if (e.getPropertyName().equals(
458: IMethoidNode.TOOLTIP_CHANGED)) {
459:
460: } else if (e.getPropertyName().equals(
461: IMethoidNode.ICON_CHANGED)) {
462: setIcon(mMethoidNode.getIcon());
463: } else if (e.getPropertyName().equals(
464: IMethoidNode.METHOID_OBJECT_CHANGED)) {
465: setName(mMethoidNode.getMethoidName());
466: setIcon(mMethoidNode.getIcon());
467: setTitle(mMethoidNode.getMethoidName());
468: }
469: }
470: }
471:
472: /**
473: * The methoid node itself does not have a tooltip per se.
474: * We instead look through our field nodes to determine if
475: * the field node at the given point has a tooltip.
476: */
477: public String getToolTipText(Point p) {
478: JGoObject fieldNode = (JGoObject) getFieldNodeByPoint(p);
479: if (fieldNode != null) {
480: return fieldNode.getToolTipText();
481: } else if (mTitleBar.getBoundingRect().contains(p)) {
482: return getMethoidNode().getToolTipText();
483: }
484: return null;
485: }
486:
487: public void setTitle(String title) {
488: mTitleBar.setTitle(title);
489: ensureBounding();
490: }
491:
492: public String getTitle() {
493: return mTitleBar.getTitle();
494: }
495:
496: public void setIcon(Icon icon) {
497: mTitleBar.setTitleIcon(((ImageIcon) icon).getImage());
498: ensureBounding();
499: }
500:
501: public void setTitleBarColor(Color color) {
502: mTitleBar.setTitleBarBackground(color);
503: }
504:
505: public void resetTitleBarColor() {
506: mTitleBar.resetTitleBarBackground();
507: }
508:
509: public Color getTitleBarColor() {
510: return mTitleBar.getTitleBarBackground();
511: }
512:
513: protected void gainedSelection(JGoSelection jgoselection) {
514: super .gainedSelection(jgoselection);
515: if (getMapperCanvas().isPathHighlightingEnabled()) {
516: new NetworkHighlightTraverser(true).visit(this );
517: }
518: }
519:
520: protected void lostSelection(JGoSelection jgoselection) {
521: super .lostSelection(jgoselection);
522: if (getMapperCanvas().isPathHighlightingEnabled()) {
523: new NetworkHighlightTraverser(false).visit(this);
524: }
525: }
526: }
|