0001: /*
0002: * The contents of this file are subject to the terms of the Common Development
0003: * and Distribution License (the License). You may not use this file except in
0004: * compliance with the License.
0005: *
0006: * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
0007: * or http://www.netbeans.org/cddl.txt.
0008: *
0009: * When distributing Covered Code, include this CDDL Header Notice in each file
0010: * and include the License file at http://www.netbeans.org/cddl.txt.
0011: * If applicable, add the following below the CDDL Header, with the fields
0012: * enclosed by brackets [] replaced by your own identifying information:
0013: * "Portions Copyrighted [year] [name of copyright owner]"
0014: *
0015: * The Original Software is NetBeans. The Initial Developer of the Original
0016: * Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun
0017: * Microsystems, Inc. All Rights Reserved.
0018: */
0019:
0020: package org.netbeans.modules.soa.mapper.basicmapper.canvas.jgo;
0021:
0022: import com.nwoods.jgo.JGoBrush;
0023: import java.awt.Component;
0024: import java.awt.Cursor;
0025: import java.awt.Point;
0026: import java.awt.dnd.DropTargetDropEvent;
0027: import java.awt.event.ComponentAdapter;
0028: import java.awt.event.ComponentEvent;
0029: import java.awt.event.InputEvent;
0030: import java.awt.event.KeyEvent;
0031: import java.awt.event.MouseEvent;
0032: import java.beans.PropertyChangeEvent;
0033: import java.beans.PropertyChangeListener;
0034: import java.util.ArrayList;
0035: import java.util.Collection;
0036: import java.util.HashSet;
0037: import java.util.Hashtable;
0038: import java.util.Iterator;
0039: import java.util.LinkedList;
0040: import java.util.List;
0041: import java.util.Map;
0042: import java.util.Set;
0043: import java.util.Vector;
0044: import java.util.logging.Level;
0045: import java.util.logging.Logger;
0046:
0047: import javax.swing.SwingUtilities;
0048:
0049: import com.nwoods.jgo.JGoDocument;
0050: import com.nwoods.jgo.JGoLayer;
0051: import com.nwoods.jgo.JGoLink;
0052: import com.nwoods.jgo.JGoListPosition;
0053: import com.nwoods.jgo.JGoObject;
0054: import com.nwoods.jgo.JGoPen;
0055: import com.nwoods.jgo.JGoPort;
0056: import com.nwoods.jgo.JGoSelection;
0057: import java.awt.dnd.DragSourceDragEvent;
0058: import java.awt.dnd.DropTargetDragEvent;
0059: import org.netbeans.modules.soa.mapper.basicmapper.MapperLink;
0060: import org.netbeans.modules.soa.mapper.basicmapper.canvas.jgo.util.DrawPort;
0061: import org.netbeans.modules.soa.mapper.basicmapper.canvas.jgo.util.PortSelection;
0062: import org.netbeans.modules.soa.mapper.common.basicmapper.canvas.IMapperCanvasView;
0063: import org.netbeans.modules.soa.mapper.common.basicmapper.canvas.gtk.ICanvasFieldNode;
0064: import org.netbeans.modules.soa.mapper.common.basicmapper.canvas.gtk.ICanvasMapperLink;
0065: import org.netbeans.modules.soa.mapper.common.basicmapper.canvas.gtk.ICanvasMethoidNode;
0066: import org.netbeans.modules.soa.mapper.common.basicmapper.canvas.gtk.ICanvasNodeToNodeLink;
0067: import org.netbeans.modules.soa.mapper.common.basicmapper.canvas.gtk.ICanvasNodeToTreeLink;
0068: import org.netbeans.modules.soa.mapper.common.basicmapper.canvas.gtk.ICanvasObjectFactory;
0069: import org.netbeans.modules.soa.mapper.common.basicmapper.canvas.gtk.ICanvasTreeToNodeLink;
0070: import org.netbeans.modules.soa.mapper.common.basicmapper.canvas.gtk.ICanvasTreeToTreeLink;
0071: import org.netbeans.modules.soa.mapper.common.basicmapper.canvas.gtk.ICanvasView;
0072: import org.netbeans.modules.soa.mapper.common.basicmapper.methoid.IFieldNode;
0073: import org.netbeans.modules.soa.mapper.common.basicmapper.methoid.IMethoidNode;
0074: import org.netbeans.modules.soa.mapper.common.basicmapper.tree.IMapperTreeNode;
0075: import org.netbeans.modules.soa.mapper.common.IMapperGroupNode;
0076: import org.netbeans.modules.soa.mapper.common.IMapperLink;
0077: import org.netbeans.modules.soa.mapper.common.IMapperNode;
0078: import org.netbeans.modules.soa.mapper.common.IMapperViewController;
0079: import org.netbeans.modules.soa.mapper.common.IMapperViewModel;
0080: import org.netbeans.modules.soa.mapper.common.gtk.ICanvasGroupNode;
0081: import org.netbeans.modules.soa.mapper.common.gtk.ICanvasLink;
0082: import org.netbeans.modules.soa.mapper.common.gtk.ICanvasMouseData;
0083: import org.netbeans.modules.soa.mapper.common.gtk.ICanvasMouseListener;
0084: import org.netbeans.modules.soa.mapper.common.gtk.ICanvasNode;
0085:
0086: /**
0087: * <p>
0088: *
0089: * Title: </p> BasicCanvasView <p>
0090: *
0091: * Description: </p> BasicCanvasView provides an implementation of a mapper
0092: * canvas view.<p>
0093: *
0094: * Copyright: Copyright (c) 2002 </p> <p>
0095: *
0096: * Company: </p>
0097: *
0098: * @author Un Seng Leong
0099: * @created December 4, 2002
0100: * @version 1.0
0101: */
0102: public class BasicCanvasView extends AbstractCanvasView {
0103:
0104: final static int MOUSE_CLICK = 1;
0105: final static int MOUSE_DBLCLICK = 2;
0106: final static int MOUSE_PRESS = 3;
0107: final static int MOUSE_RELEASE = 4;
0108: final static int MOUSE_MOVE = 5;
0109:
0110: /**
0111: * the log instance of this class
0112: */
0113: private Logger mLogger = Logger.getLogger(BasicCanvasView.class
0114: .getName());
0115:
0116: /**
0117: * Listener listens on the change of the mapper view model.
0118: */
0119: private PropertyChangeListener mViewModelListener = new ViewModelChangeListener();
0120:
0121: /**
0122: * Contains the link with at least one side connected to a tree.
0123: */
0124: private List mFilterTreeNodeLink = new Vector();
0125:
0126: /**
0127: * Contains the link with node to node links
0128: */
0129: private List mFilterNodeLinks = new Vector();
0130:
0131: /**
0132: * Caching the jgo layer and the mapper view model.
0133: */
0134: private Map mLayerModelMap;
0135:
0136: /**
0137: * Listener listens on the add and remove link in each of the node in the
0138: * view model and group node.
0139: */
0140: private PropertyChangeListener mNodeLinkListener;
0141:
0142: /**
0143: * Listener listens on the add and remove node in a group node.
0144: */
0145: private PropertyChangeListener mGroupNodeListener;
0146:
0147: /**
0148: * Canvas object factory to produce canvas object.
0149: */
0150: private ICanvasObjectFactory mObjectFactory;
0151:
0152: /**
0153: * the unique layer to be display.
0154: */
0155: private JGoLayer mSelectedLayer;
0156:
0157: /**
0158: * the default cursor
0159: */
0160: private Cursor mDefaultCursor = Cursor.getDefaultCursor();
0161:
0162: /**
0163: * the linking cursor
0164: */
0165: //private Cursor mLinkCursor = Cursor.getPredefinedCursor(Cursor.CROSSHAIR_CURSOR);
0166: private Cursor mLinkCursor = Cursor
0167: .getPredefinedCursor(Cursor.HAND_CURSOR);
0168:
0169: /**
0170: * the moving node cursor
0171: */
0172: private Cursor mMoveCursor = Cursor
0173: .getPredefinedCursor(Cursor.MOVE_CURSOR);
0174:
0175: /**
0176: * the link in this list is waiting for another end of the node to be added
0177: * to the canvas, link cannot be display without either end not in the canvas.
0178: */
0179: private List mNewLinkList;
0180:
0181: private HoverPort mCurrentTargetHoverPort;
0182: private HoverPort mCurrentSourceHoverPort;
0183: private Point mDropLocation;
0184: private int mDropAction;
0185: private Set mMouseListeners = new HashSet();
0186:
0187: /**
0188: * Construct a new Canvas View. This canvas contains no vertical bar, but
0189: * horizontal bar.
0190: *
0191: * @param view the parent mapper view contains this canvas
0192: */
0193: public BasicCanvasView(IMapperCanvasView view) {
0194: super (view);
0195: this .setHidingDisabledScrollbars(true);
0196:
0197: setDocument(new JGoDocument());
0198:
0199: addComponentListener(new CanvasSizeListener());
0200: mNodeLinkListener = new NodeLinkListener(this );
0201: mGroupNodeListener = new GroupNodeListener();
0202: mLayerModelMap = new Hashtable();
0203: setDefaultPrimarySelectionColor(ICanvasMapperLink.DEFAULT_LINK_SELECTED_COLOR);
0204:
0205: mObjectFactory = new BasicCanvasObjectFactory();
0206: mObjectFactory.setMapperCanvas(this );
0207: mNewLinkList = new Vector();
0208: setDefaultPortGravity(20);
0209: }
0210:
0211: /**
0212: * Return a canvas link that contains the mapper link, or null if no such
0213: * mapper link.
0214: *
0215: * @param dataObject the mapper link
0216: * @return a canvas link that contains the mapper link, or null
0217: * if no such mapper link.
0218: */
0219: public ICanvasLink getCanvasLinkByDataObject(Object dataObject) {
0220: if (!(dataObject instanceof IMapperLink)) {
0221: return null;
0222: }
0223:
0224: IMapperLink matchLink = (IMapperLink) dataObject;
0225:
0226: JGoDocument model = this .getDocument();
0227: JGoListPosition pos = model.getFirstObjectPos();
0228: JGoObject obj = null;
0229:
0230: for (; pos != null; pos = model.getNextObjectPos(pos)) {
0231: obj = model.getObjectAtPos(pos);
0232:
0233: if (obj instanceof ICanvasMapperLink
0234: && (((ICanvasMapperLink) obj).getMapperLink() == matchLink)) {
0235: return (ICanvasLink) obj;
0236: }
0237: }
0238:
0239: return null;
0240: }
0241:
0242: /**
0243: * Return the canvas node repersetns the data object. Currently, the data
0244: * object should be IMethoidFieldNode or IMethoidNode, or return null if
0245: * data object is either of the them, or no each object in this canvas.
0246: *
0247: * @param dataObject the data object to match
0248: * @return the canvas node repersents the data object.
0249: */
0250: public ICanvasNode getCanvasNodeByDataObject(Object dataObject) {
0251: if (dataObject instanceof IFieldNode) {
0252: return findCanvasFieldNode((IFieldNode) dataObject);
0253: }
0254:
0255: if (dataObject instanceof IMethoidNode) {
0256: return findCanvasMethoidNode((IMethoidNode) dataObject);
0257: }
0258:
0259: return null;
0260: }
0261:
0262: /**
0263: * Return the canvas object factory for this canvas.
0264: *
0265: * @return the canvas object factory.
0266: */
0267: public ICanvasObjectFactory getCanvasObjectFactory() {
0268: return mObjectFactory;
0269: }
0270:
0271: /**
0272: * Return all the nodes in the currect layer.
0273: *
0274: * @return all the nodes in the currect layer.
0275: */
0276: public List getNodes() {
0277: List nodes = new ArrayList();
0278:
0279: if (mSelectedLayer == null) {
0280: return nodes;
0281: }
0282:
0283: for (JGoListPosition pos = mSelectedLayer.getFirstObjectPos(); pos != null; pos = mSelectedLayer
0284: .getNextObjectPos(pos)) {
0285: nodes.add(mSelectedLayer.getObjectAtPos(pos));
0286: }
0287:
0288: return nodes;
0289: }
0290:
0291: /**
0292: * Retrieves model object at the given location
0293: *
0294: * @param modelCor Description of the Parameter
0295: * @param flag Description of the Parameter
0296: * @return The objectInModel value
0297: */
0298: public Object getObjectInModel(Point modelCor, boolean flag) {
0299: return mSelectedLayer.pickObject(modelCor, flag);
0300: }
0301:
0302: public Object getPortObjectInModel(Point modelCor, boolean flag) {
0303: JGoPort object = pickNearestPort(modelCor);
0304: if (object != null) {
0305: return object;
0306: }
0307: return mSelectedLayer.pickObject(modelCor, flag);
0308: }
0309:
0310: /**
0311: * Retrieves a collection of selected links
0312: *
0313: * @return The selectedLinks value
0314: */
0315: public Collection getSelectedLinks() {
0316: List list = new ArrayList();
0317: JGoSelection selection = this .getSelection();
0318:
0319: if (selection == null) {
0320: return list;
0321: }
0322:
0323: JGoObject obj = null;
0324: JGoListPosition pos = selection.getFirstObjectPos();
0325:
0326: while (pos != null) {
0327: obj = selection.getObjectAtPos(pos);
0328:
0329: if (obj instanceof ICanvasLink) {
0330: list.add(obj);
0331: }
0332:
0333: pos = selection.getNextObjectPos(pos);
0334: }
0335:
0336: return list;
0337: }
0338:
0339: /**
0340: * Retrieves a list of selected nodes
0341: *
0342: * @return List
0343: */
0344: public Collection getSelectedNodes() {
0345: List list = new ArrayList();
0346: JGoSelection selection = this .getSelection();
0347:
0348: if (selection == null) {
0349: return list;
0350: }
0351:
0352: JGoObject obj = null;
0353: JGoListPosition pos = selection.getFirstObjectPos();
0354:
0355: while (pos != null) {
0356: obj = selection.getObjectAtPos(pos);
0357:
0358: if (obj instanceof ICanvasNode) {
0359: list.add(obj);
0360: }
0361:
0362: pos = selection.getNextObjectPos(pos);
0363: }
0364:
0365: return list;
0366: }
0367:
0368: /**
0369: * Return the Look and Feel of this canvas. The method return "this".
0370: *
0371: * @return the compoenent repersents this canvas look and feel.
0372: */
0373: public Component getUIComponent() {
0374: return this ;
0375: }
0376:
0377: /**
0378: * Return true if the canvas node is existed in the canvas model.
0379: *
0380: * @param node the specified node to be searched.
0381: * @return The nodeExisit value
0382: */
0383: public boolean isNodeExisit(ICanvasNode node) {
0384: JGoListPosition result = getDocument().findObject(
0385: (JGoObject) node);
0386:
0387: if (result == null) {
0388: return false;
0389: }
0390:
0391: if (!allContainersExpanded(node)) {
0392: return false;
0393: }
0394:
0395: return ((JGoObject) node).isVisible();
0396: }
0397:
0398: /**
0399: * Set the canvas object factory for this canvas.
0400: *
0401: * @param factory the canvas object factory
0402: */
0403: public void setCanvasObjectFactory(ICanvasObjectFactory factory) {
0404: mObjectFactory = factory;
0405: }
0406:
0407: /**
0408: * Set the mapper view model for this canvas.
0409: *
0410: * @param viewModel the mapper view model for this canvas.
0411: */
0412: public void setViewModel(IMapperViewModel viewModel) {
0413: IMapperViewModel oldModel = getParentView().getViewModel();
0414: this .clearSelection();
0415:
0416: if (oldModel != null) {
0417: oldModel.removePropertyChangeListener(mViewModelListener);
0418: }
0419:
0420: if (viewModel != null) {
0421: viewModel.addPropertyChangeListener(mViewModelListener);
0422:
0423: // create a JGo Layer for each view so that we don't have to
0424: // create all the JGo objects for each view model
0425: if (mLayerModelMap.containsKey(viewModel)) {
0426: mSelectedLayer.setVisible(false);
0427: mSelectedLayer = (JGoLayer) mLayerModelMap
0428: .get(viewModel);
0429: mSelectedLayer.setVisible(true);
0430: getDocument().setDefaultLayer(mSelectedLayer);
0431: } else {
0432: if (mSelectedLayer == null) {
0433: mSelectedLayer = this .getDocument()
0434: .getDefaultLayer();
0435: } else {
0436: mSelectedLayer.setVisible(false);
0437: mSelectedLayer = getDocument().addLayerBefore(
0438: mSelectedLayer);
0439: }
0440:
0441: getDocument().setDefaultLayer(mSelectedLayer);
0442: mSelectedLayer.setVisible(true);
0443: mLayerModelMap.put(viewModel, mSelectedLayer);
0444: initializeCanvasNode(viewModel);
0445: }
0446: }
0447: }
0448:
0449: /**
0450: * Add a link to this canvas to display
0451: *
0452: * @param link the specified link to be added.
0453: */
0454: public void addLink(ICanvasLink link) {
0455: if (mSelectedLayer == null) {
0456: mSelectedLayer = this .getDocument().getDefaultLayer();
0457: }
0458:
0459: mSelectedLayer.addObjectAtHead((JGoObject) link);
0460:
0461: if (link instanceof ICanvasNodeToTreeLink
0462: || link instanceof ICanvasTreeToNodeLink
0463: || link instanceof ICanvasTreeToTreeLink) {
0464: mFilterTreeNodeLink.add(link);
0465: }
0466:
0467: if (link instanceof ICanvasNodeToNodeLink) {
0468: mFilterNodeLinks.add(link);
0469: }
0470: }
0471:
0472: /**
0473: * Add a node a this canvas to display.
0474: *
0475: * @param node the specified node to be added.
0476: */
0477: public void addNode(ICanvasNode node) {
0478: if (mSelectedLayer == null) {
0479: mSelectedLayer = this .getDocument().getDefaultLayer();
0480: }
0481:
0482: // Need to clear selection for new object, otherwise, the selection
0483: // box may appear on top of the new object
0484: clearSelection();
0485: mSelectedLayer.addObjectAtTail((JGoObject) node);
0486:
0487: }
0488:
0489: /**
0490: * Retrun true if the container expended, false otherwise.
0491: *
0492: * @param node the container node.
0493: * @return Retrun true if the container expended, false otherwise.
0494: */
0495: public boolean allContainersExpanded(ICanvasNode node) {
0496: ICanvasGroupNode container = node.getContainer();
0497:
0498: if (container == null) {
0499: return true;
0500: } else {
0501: return container.isExpanded()
0502: && allContainersExpanded(container);
0503: }
0504: }
0505:
0506: /**
0507: * Clear the selection. No object will be selected.
0508: */
0509: public void clearSelection() {
0510: this .getSelection().clearSelection();
0511: }
0512:
0513: /**
0514: * Collapse all Methoid Node in the current layer.
0515: */
0516: public void collapseAllNode() {
0517: for (JGoListPosition pos = mSelectedLayer.getFirstObjectPos(); pos != null; pos = mSelectedLayer
0518: .getNextObjectPos(pos)) {
0519: JGoObject jgoObj = mSelectedLayer.getObjectAtPos(pos);
0520:
0521: if (jgoObj instanceof BasicCanvasMethoidNode) {
0522: ((BasicCanvasMethoidNode) jgoObj).collapse();
0523: }
0524: }
0525: }
0526:
0527: /**
0528: * Create link from dragging on this canvas to other view. This method
0529: * provide the way for user to drag a JGoPort (connection object of
0530: * ICanvasFieldNode) to other view to create a link.
0531: *
0532: * @param link the link to be created, should has only 1 end (start or end
0533: * node) null.
0534: * @return Return true if the link is create successfull, false
0535: * otherwise.
0536: */
0537: public boolean connectLinkByDrag(IMapperLink link) {
0538: Point convertedPoint = getDnDDragOrginPoint();
0539: convertViewToDoc(convertedPoint);
0540:
0541: return connectLinkByPoint(convertedPoint, link);
0542: }
0543:
0544: /**
0545: * Return true if the specified mapper link can be connected by a mapper
0546: * node that can be found by the specified point, false otherwise.
0547: *
0548: * @param docPoint the point where the mapper node to be found, in the
0549: * document point system.
0550: * @param link the link that should has 1 end does not connected to any
0551: * nodes.
0552: * @return true if a canvas link contains the specified mapper link
0553: * can be created, false otherwise.
0554: */
0555: public boolean connectLinkByPoint(Point docPoint, IMapperLink link) {
0556: JGoLayer layer = mSelectedLayer;
0557: JGoObject dropObject = (JGoObject) getPortObjectInModel(
0558: docPoint, false);
0559:
0560: ICanvasFieldNode dropFieldNode = null;
0561: if (dropObject instanceof JGoPort) {
0562: dropFieldNode = findCanvasFieldNodeByConnectionObject(
0563: layer, dropObject);
0564: if (dropFieldNode == null) {
0565: return false;
0566: }
0567: } else {
0568: return false;
0569: }
0570: IFieldNode dragEndNode = dropFieldNode.getFieldNode();
0571: IMapperNode dragStartNode = link.getStartNode() == null ? link
0572: .getEndNode() : link.getStartNode();
0573: boolean requiresInput = false;
0574: if (dragStartNode instanceof IMapperTreeNode) {
0575: requiresInput = ((IMapperTreeNode) dragStartNode)
0576: .isSourceTreeNode();
0577: } else if (dragStartNode instanceof IFieldNode) {
0578: requiresInput = ((IFieldNode) dragStartNode).isOutput();
0579: } else {
0580: throw new Error("This shouldn't have happened...");
0581: }
0582: if (requiresInput) {
0583: if (!dragEndNode.isInput()) {
0584: return false;
0585: }
0586: } else {
0587: if (!dragEndNode.isOutput()) {
0588: return false;
0589: }
0590: }
0591: if (link.getStartNode() == null) {
0592: ((MapperLink) link).setStartNode(dragEndNode);
0593: } else {
0594: ((MapperLink) link).setEndNode(dragEndNode);
0595: }
0596: ((IMapperViewController) this .getCanvasController())
0597: .requestNewLink(link);
0598: return true;
0599: }
0600:
0601: /**
0602: * Return the canvas field node contains the specified connection object in
0603: * a given layer, or null if no filed node contains the connection object.
0604: *
0605: * @param layer the layer to be search on
0606: * @param connObject the object to be match
0607: * @return the canvas field node contains the specified
0608: * connection object in a given layer, or null if no filed node
0609: * contains the connection object.
0610: */
0611: private ICanvasFieldNode findCanvasFieldNodeByConnectionObject(
0612: JGoLayer layer, Object connObject) {
0613: ICanvasFieldNode canvasFieldNode = null;
0614: Collection canvasFieldNodes = null;
0615: ICanvasMethoidNode dragMethoidNode = null;
0616: ICanvasFieldNode dragFieldNode = null;
0617:
0618: for (JGoListPosition pos = layer.getFirstObjectPos(); pos != null; pos = layer
0619: .getNextObjectPos(pos)) {
0620: JGoObject jgoObj = layer.getObjectAtPos(pos);
0621:
0622: if (!(jgoObj instanceof ICanvasMethoidNode)) {
0623: continue;
0624: }
0625:
0626: dragMethoidNode = (ICanvasMethoidNode) jgoObj;
0627:
0628: if ((dragFieldNode = dragMethoidNode
0629: .getFieldNodeByConnectPointObject(connObject)) != null) {
0630: break;
0631: }
0632: }
0633: return dragFieldNode;
0634: }
0635:
0636: /**
0637: * Handles delete the selected object. Actural work is delegated to
0638: * controller.
0639: */
0640: public void deleteSelection() {
0641: if (getCanvasController() != null) {
0642: getCanvasController().handleDeleteSelection();
0643: } else {
0644: doDefaultDeleteSelection();
0645: }
0646: }
0647:
0648: /**
0649: * Wrapper method for the default delection selection, always return true.
0650: *
0651: * @return always true
0652: */
0653: public boolean doDefaultDeleteSelection() {
0654: super .deleteSelection();
0655: return true;
0656: }
0657:
0658: /**
0659: * Sets the Cursor icon on mouse over (when no other mouse events occur)
0660: *
0661: * @param modifiers modifiers
0662: * @param dc dc
0663: * @param vc vc
0664: */
0665: public void doUncapturedMouseMove(int modifiers, Point dc, Point vc) {
0666: Object obj = pickDocObject(dc, true);
0667: Cursor cursor = mDefaultCursor;
0668:
0669: markCurrentHoverPort(dc, false);
0670:
0671: if (obj instanceof BasicCanvasMethoidNode) {
0672: BasicCanvasMethoidNode methoidNode = (BasicCanvasMethoidNode) obj;
0673: if (!methoidNode.isExpanded()) {
0674: if (!methoidNode.isInButton(vc)) {
0675: cursor = mMoveCursor;
0676: }
0677: } else {
0678: for (JGoListPosition pos = methoidNode
0679: .getFirstObjectPos(); pos != null; pos = methoidNode
0680: .getNextObjectPos(pos)) {
0681:
0682: JGoObject jgoObj = methoidNode.getObjectAtPos(pos);
0683: if (jgoObj.getBoundingRect().contains(dc)) {
0684: if (jgoObj instanceof BasicTitleBarUI) {
0685: if (!((BasicTitleBarUI) jgoObj)
0686: .isInButton(vc)) {
0687: cursor = mMoveCursor;
0688: }
0689: break;
0690: } else if (jgoObj instanceof JGoPort) {
0691: cursor = mLinkCursor;
0692: break;
0693: }
0694: }
0695: }
0696: }
0697: }
0698: setCursor(cursor);
0699: }
0700:
0701: // Override to set up the source hover port.
0702: // The source hover port is only created if the source of the drag
0703: // was a port of a methoid.
0704: public JGoLink createTemporaryLinkForNewLink(JGoPort from,
0705: JGoPort to) {
0706: JGoLink link = super .createTemporaryLinkForNewLink(from, to);
0707:
0708: link.setPen(JGoPen.make(JGoPen.SOLID, 1,
0709: ICanvasMapperLink.DEFAULT_LINK_SELECTED_COLOR));
0710: link
0711: .setBrush(JGoBrush
0712: .makeStockBrush(ICanvasMapperLink.DEFAULT_LINK_SELECTED_COLOR));
0713:
0714: if (from instanceof BasicCanvasPort) {
0715: mCurrentSourceHoverPort = new HoverPort(
0716: ((BasicCanvasPort) from).getDrawPort());
0717: mCurrentSourceHoverPort.set(true);
0718: } else if (to instanceof BasicCanvasPort) {
0719: mCurrentSourceHoverPort = new HoverPort(
0720: ((BasicCanvasPort) to).getDrawPort());
0721: mCurrentSourceHoverPort.set(true);
0722: }
0723: return link;
0724: }
0725:
0726: // When dragging is done, this method is called.
0727: // We simply clean up our source hover port.
0728: public void removeRawLink(ICanvasLink link) {
0729: super .removeRawLink(link);
0730: if (mCurrentSourceHoverPort != null) {
0731: mCurrentSourceHoverPort.unset();
0732: mCurrentSourceHoverPort = null;
0733: }
0734: }
0735:
0736: public void dragOver(DropTargetDragEvent dtde) {
0737: super .dragOver(dtde);
0738: markCurrentHoverPort(dtde.getLocation(), true);
0739: }
0740:
0741: public void dragOver(DragSourceDragEvent dsde) {
0742: super .dragOver(dsde);
0743: Point point = dsde.getLocation();
0744: Point screenReferencePoint = this .getLocationOnScreen();
0745: point.translate(-screenReferencePoint.x,
0746: -screenReferencePoint.y);
0747: markCurrentHoverPort(point, true);
0748: }
0749:
0750: // Manages the source and target hover ports during mouse moving/dragging.
0751: private void markCurrentHoverPort(Point point, boolean isActivated) {
0752: if (mCurrentTargetHoverPort != null) {
0753: mCurrentTargetHoverPort.unset();
0754: }
0755:
0756: if (mCurrentSourceHoverPort != null) {
0757: mCurrentSourceHoverPort.set(true);
0758: }
0759:
0760: Object obj = pickDocObject(point, true);
0761: if (obj instanceof BasicCanvasMethoidNode) {
0762: BasicCanvasMethoidNode methoidNode = (BasicCanvasMethoidNode) obj;
0763: if (methoidNode.isExpanded()) {
0764: for (JGoListPosition pos = methoidNode
0765: .getFirstObjectPos(); pos != null; pos = methoidNode
0766: .getNextObjectPos(pos)) {
0767: JGoObject jgoObj = methoidNode.getObjectAtPos(pos);
0768: if (jgoObj.getBoundingRect().contains(point)) {
0769: if (jgoObj instanceof BasicCanvasFieldNode) {
0770: BasicCanvasFieldNode field = (BasicCanvasFieldNode) jgoObj;
0771: if (field.getDrawPort() != null) {
0772: mCurrentTargetHoverPort = new HoverPort(
0773: field);
0774: mCurrentTargetHoverPort
0775: .set(isActivated);
0776: return;
0777: }
0778: }
0779: }
0780: }
0781: }
0782: }
0783:
0784: JGoPort port = pickNearestPort(point);
0785: if (port instanceof BasicCanvasPort) {
0786: BasicCanvasPort basicCanvasPort = (BasicCanvasPort) port;
0787: if (basicCanvasPort.getDrawPort() != null) {
0788: mCurrentTargetHoverPort = new HoverPort(basicCanvasPort
0789: .getDrawPort());
0790: mCurrentTargetHoverPort.set(isActivated);
0791: }
0792: }
0793: }
0794:
0795: /**
0796: * Handles default mouse click behavior
0797: *
0798: * @param data the mouse data of the double click event
0799: * @return true if default mouse click is processed successfully, false
0800: * otherwise.
0801: */
0802: public boolean doDefaultMouseClick(ICanvasMouseData data) {
0803: if (fireMouseEvent(MOUSE_CLICK, data)) {
0804: return true;
0805: }
0806: return doDefaultMouseClick(data.getMouseModifier(), data
0807: .getModelLocation(), data.getViewLocation());
0808: }
0809:
0810: /**
0811: * Wrapper method for the default mouse click
0812: *
0813: * @param modifier the modifier
0814: * @param docLocation the documentation location
0815: * @param viewLocation the view location
0816: * @return true if default mouse click is processed
0817: * successfully, false otherwise.
0818: */
0819: public boolean doDefaultMouseClick(int modifier, Point docLocation,
0820: Point viewLocation) {
0821: // just call jgo
0822: return super .doMouseClick(modifier, docLocation, viewLocation);
0823: }
0824:
0825: /**
0826: * Handles default mouse double click behavior
0827: *
0828: * @param data the mouse data of event
0829: * @return true if default mouse double click is processed
0830: * successfully, false otherwise.
0831: */
0832: public boolean doDefaultMouseDblClick(ICanvasMouseData data) {
0833: // called from controller
0834: if (fireMouseEvent(MOUSE_DBLCLICK, data)) {
0835: return true;
0836: }
0837: return doDefaultMouseDblClick(data.getMouseModifier(), data
0838: .getModelLocation(), data.getViewLocation());
0839: }
0840:
0841: /**
0842: * Wrapper method for the default mouse double click
0843: *
0844: * @param modifier the modifier
0845: * @param docLocation the documentation location
0846: * @param viewLocation the view location
0847: * @return true if default mouse double click is processed
0848: * successfully, false otherwise.
0849: */
0850: public boolean doDefaultMouseDblClick(int modifier,
0851: Point docLocation, Point viewLocation) {
0852: // call jgo
0853: return super .doMouseDblClick(modifier, docLocation,
0854: viewLocation);
0855: }
0856:
0857: /**
0858: * Handles default mouse down behavior
0859: *
0860: * @param data the mouse data of event
0861: * @return true if default mouse button pressed is processed
0862: * successfully, false otherwise.
0863: */
0864: public boolean doDefaultMouseDown(ICanvasMouseData data) {
0865: if (fireMouseEvent(MOUSE_PRESS, data)) {
0866: return true;
0867: }
0868: return doDefaultMouseDown(data.getMouseModifier(), data
0869: .getModelLocation(), data.getViewLocation());
0870: }
0871:
0872: /**
0873: * The wrapper method for the default mouse down
0874: *
0875: * @param modifier the modifier
0876: * @param docLocation the documentation location
0877: * @param viewLocation the view location
0878: * @return true if default mouse button pressed is processed
0879: * successfully, false otherwise.
0880: */
0881: public boolean doDefaultMouseDown(int modifier, Point docLocation,
0882: Point viewLocation) {
0883: // just call jgo..
0884: return super .doMouseDown(modifier, docLocation, viewLocation);
0885: }
0886:
0887: /**
0888: * Handles default mouse move behavior
0889: *
0890: * @param data the mouse data of event
0891: * @return true if default mouse moved is processed successfully, false
0892: * otherwise.
0893: */
0894: public boolean doDefaultMouseMove(ICanvasMouseData data) {
0895: if (fireMouseEvent(MOUSE_MOVE, data)) {
0896: return true;
0897: }
0898: return doDefaultMouseMove(data.getMouseModifier(), data
0899: .getModelLocation(), data.getViewLocation());
0900: }
0901:
0902: /**
0903: * Wrapper method for the default mouse move
0904: *
0905: * @param modifier the modifier
0906: * @param docLocation the documentation location
0907: * @param viewLocation the view location
0908: * @return true if default mouse moved is processed
0909: * successfully, false otherwise.
0910: */
0911: public boolean doDefaultMouseMove(int modifier, Point docLocation,
0912: Point viewLocation) {
0913: // just call jgo
0914: return super .doMouseMove(modifier, docLocation, viewLocation);
0915: }
0916:
0917: /**
0918: * Handles default mouse up behavior
0919: *
0920: * @param data the mouse data of event
0921: * @return true if default mouse button released is processed
0922: * successfully, false otherwise.
0923: */
0924: public boolean doDefaultMouseUp(ICanvasMouseData data) {
0925: // called by controller
0926: if (fireMouseEvent(MOUSE_RELEASE, data)) {
0927: return true;
0928: }
0929:
0930: boolean result = doDefaultMouseUp(data.getMouseModifier(), data
0931: .getModelLocation(), data.getViewLocation());
0932:
0933: // hack to get the popup menu to show upon a right-click on empty canvas.
0934: // getState() returns 0 if the mouse was pressed on empty canvas.
0935: int mods = data.getMouseModifier();
0936: if (getState() == 0 && (mods & InputEvent.BUTTON1_MASK) == 0) {
0937: doDefaultMouseClick(data);
0938: }
0939:
0940: return result;
0941: }
0942:
0943: /**
0944: * Wrapper method for the default mouse up
0945: *
0946: * @param modifier the modifier
0947: * @param docLocation the documentation location
0948: * @param viewLocation the view location
0949: * @return true if default mouse button released is processed
0950: * successfully, false otherwise.
0951: */
0952: public boolean doDefaultMouseUp(int modifier, Point docLocation,
0953: Point viewLocation) {
0954: if (mCurrentSourceHoverPort != null) {
0955: mCurrentSourceHoverPort.unset();
0956: mCurrentSourceHoverPort = null;
0957: }
0958: return super .doMouseUp(modifier, docLocation, viewLocation);
0959: }
0960:
0961: /**
0962: * Handles mouse click - actual work is delegated to the controller
0963: *
0964: * @param modifier the modifier
0965: * @param docLocation the documentation location
0966: * @param viewLocation the view location
0967: * @return true if default mouse button clicked is processed
0968: * successfully, false otherwise.
0969: */
0970: public boolean doMouseClick(int modifier, Point docLocation,
0971: Point viewLocation) {
0972: // called by jgo
0973: if (getCanvasController() != null) {
0974: BasicCanvasMouseData data = new BasicCanvasMouseData(this ,
0975: modifier, docLocation, viewLocation);
0976: return getCanvasController().handleMouseClick(data);
0977: }
0978: return doDefaultMouseClick(modifier, docLocation, viewLocation);
0979: }
0980:
0981: /**
0982: * Handles mouse double click - actual work is delegated to the controller
0983: *
0984: * @param modifier the modifier
0985: * @param docLocation the documentation location
0986: * @param viewLocation the view location
0987: * @return true if default mouse button double clicked is
0988: * processed successfully, false otherwise.
0989: */
0990: public boolean doMouseDblClick(int modifier, Point docLocation,
0991: Point viewLocation) {
0992: if (getCanvasController() != null) {
0993: BasicCanvasMouseData data = new BasicCanvasMouseData(this ,
0994: modifier, docLocation, viewLocation);
0995: return getCanvasController().handleMouseDblClick(data);
0996: }
0997: return doDefaultMouseDblClick(modifier, docLocation,
0998: viewLocation);
0999: }
1000:
1001: /**
1002: * Handles mouse up - actual work is delegated to the controller
1003: *
1004: * @param modifier the modifier
1005: * @param docLocation the documentation location
1006: * @param viewLocation the view location
1007: * @return true if default mouse button up is
1008: * processed successfully, false otherwise.
1009: */
1010: public boolean doMouseUp(int modifier, Point docLocation,
1011: Point viewLocation) {
1012: // called by jgo
1013: if (getCanvasController() != null) {
1014: BasicCanvasMouseData data = new BasicCanvasMouseData(this ,
1015: modifier, docLocation, viewLocation);
1016: return getCanvasController().handleMouseUp(data);
1017: }
1018: return doDefaultMouseUp(modifier, docLocation, viewLocation);
1019: }
1020:
1021: /**
1022: * Handles mouse down - actual work is delegated to the controller
1023: *
1024: * @param modifier the modifier
1025: * @param docLocation the documentation location
1026: * @param viewLocation the view location
1027: * @return true if default mouse button down is
1028: * processed successfully, false otherwise.
1029: */
1030: public boolean doMouseDown(int modifier, Point docLocation,
1031: Point viewLocation) {
1032: // called by jgo
1033: if (getCanvasController() != null) {
1034: BasicCanvasMouseData data = new BasicCanvasMouseData(this ,
1035: modifier, docLocation, viewLocation);
1036: return getCanvasController().handleMouseDown(data);
1037: }
1038: return doDefaultMouseDown(modifier, docLocation, viewLocation);
1039: }
1040:
1041: /**
1042: * Handles mouse move - actual work is delegated to the controller
1043: *
1044: * @param modifier the modifier
1045: * @param docLocation the documentation location
1046: * @param viewLocation the view location
1047: * @return true if default mouse button move is
1048: * processed successfully, false otherwise.
1049: */
1050: public boolean doMouseMove(int modifier, Point docLocation,
1051: Point viewLocation) {
1052: // called by jgo
1053: if (getCanvasController() != null) {
1054: BasicCanvasMouseData data = new BasicCanvasMouseData(this ,
1055: modifier, docLocation, viewLocation);
1056: return getCanvasController().handleMouseMove(data);
1057: }
1058: return doDefaultMouseMove(modifier, docLocation, viewLocation);
1059: }
1060:
1061: /**
1062: * Expend all Methoid Node in the current layer.
1063: */
1064: public void expendAllNode() {
1065: for (JGoListPosition pos = mSelectedLayer.getFirstObjectPos(); pos != null; pos = mSelectedLayer
1066: .getNextObjectPos(pos)) {
1067: JGoObject jgoObj = mSelectedLayer.getObjectAtPos(pos);
1068:
1069: if (jgoObj instanceof BasicCanvasMethoidNode) {
1070: ((BasicCanvasMethoidNode) jgoObj).expand();
1071: }
1072: }
1073: }
1074:
1075: /**
1076: * Return a default location for the specified new node that will possible
1077: * add to this canvas view. Currently, the new node is not use.
1078: *
1079: * @param newNode the node to be use to calculate the new location.
1080: * @return a point where the defualt location of the new node.
1081: */
1082: public Point getDefaultLocationForNewNode(IMethoidNode newNode) {
1083: Point defaultPoint = new Point(getViewPosition());
1084: JGoObject findNode = null;
1085: int shift = 1;
1086: do {
1087: defaultPoint.x += 10;
1088: defaultPoint.y += 10;
1089: if (defaultPoint.y >= getExtentSize().height) {
1090: defaultPoint.x = getViewPosition().x + (shift++ * 40);
1091: defaultPoint.y = getViewPosition().y + 10;
1092: }
1093: findNode = mSelectedLayer.pickObject(defaultPoint, false);
1094: } while (findNode != null
1095: && findNode.getLocation().equals(defaultPoint));
1096:
1097: return defaultPoint;
1098: }
1099:
1100: /**
1101: * Retrun the canvas field node that repersents the specifeid mapper field
1102: * node. Or null if the specified field node cannot be found.
1103: *
1104: * @param fieldNode the mapper field node
1105: * @return the canvas node that warps the mapper field node.
1106: */
1107: public ICanvasFieldNode findCanvasFieldNode(IFieldNode fieldNode) {
1108: JGoDocument jgoModel = this .getDocument();
1109: JGoListPosition pos = null;
1110: JGoObject jgoObj = null;
1111: ICanvasFieldNode canvasFieldNode = null;
1112: Collection canvasFieldNodes = null;
1113:
1114: for (pos = jgoModel.getFirstObjectPos(); pos != null; pos = jgoModel
1115: .getNextObjectPos(pos)) {
1116: jgoObj = jgoModel.getObjectAtPos(pos);
1117:
1118: if (!(jgoObj instanceof ICanvasMethoidNode)) {
1119: continue;
1120: }
1121: ICanvasMethoidNode methoidNode = (ICanvasMethoidNode) jgoObj;
1122:
1123: canvasFieldNodes = methoidNode.getNodes();
1124:
1125: Iterator iterator = canvasFieldNodes.iterator();
1126:
1127: while (iterator.hasNext()) {
1128: canvasFieldNode = (ICanvasFieldNode) iterator.next();
1129:
1130: if (canvasFieldNode.getFieldNode() == fieldNode) {
1131: return canvasFieldNode;
1132: }
1133: }
1134: }
1135:
1136: return null;
1137: }
1138:
1139: /**
1140: * Search and return the canvas methoid node that repersents the specified
1141: * mapper methoid node.
1142: *
1143: * @param methoidNode Description of the Parameter
1144: * @return Description of the Return Value
1145: */
1146: public ICanvasMethoidNode findCanvasMethoidNode(
1147: IMethoidNode methoidNode) {
1148: JGoDocument jgoModel = this .getDocument();
1149: JGoListPosition pos = null;
1150: JGoObject jgoObj = null;
1151: ICanvasMethoidNode canvasMethoidNode = null;
1152:
1153: for (pos = jgoModel.getFirstObjectPos(); pos != null; pos = jgoModel
1154: .getNextObjectPos(pos)) {
1155: jgoObj = jgoModel.getObjectAtPos(pos);
1156:
1157: if (!(jgoObj instanceof ICanvasMethoidNode)) {
1158: continue;
1159: }
1160: ICanvasMethoidNode methoidCanvasNode = (ICanvasMethoidNode) jgoObj;
1161:
1162: if (methoidCanvasNode.getMethoidNode() == methoidNode) {
1163: return methoidCanvasNode;
1164: }
1165: }
1166:
1167: return null;
1168: }
1169:
1170: /**
1171: * Return a canvas methoid node that contains the specified point in its
1172: * bounding.
1173: *
1174: * @param point the point to be matched
1175: * @return a canvas methoid node that contains the specified point in
1176: * its bounding
1177: */
1178: public ICanvasMethoidNode getCanvasMethoidNodeByPoint(Point point) {
1179: Point docPt = new Point(point);
1180: this .convertViewToDoc(docPt);
1181: for (JGoListPosition pos = mSelectedLayer.getFirstObjectPos(); pos != null; pos = mSelectedLayer
1182: .getNextObjectPos(pos)) {
1183: JGoObject obj = mSelectedLayer.getObjectAtPos(pos);
1184: if (obj instanceof ICanvasMethoidNode
1185: && obj.getBoundingRect().contains(docPt)) {
1186: return (ICanvasMethoidNode) obj;
1187: }
1188: }
1189: return null;
1190: }
1191:
1192: /**
1193: * Return a canvas field node that contains the specified point in its
1194: * bounding.
1195: *
1196: * @param point the point to be matched
1197: * @return a canvas field node that contains the specified point in
1198: * its bounding
1199: */
1200: public ICanvasFieldNode getCanvasFieldNodeByPoint(Point point) {
1201: Point docPt = new Point(point);
1202: this .convertViewToDoc(docPt);
1203: ICanvasMethoidNode methoidNode = getCanvasMethoidNodeByPoint(point);
1204: if (methoidNode != null) {
1205: return methoidNode.getFieldNodeByPoint(docPt);
1206: }
1207: return null;
1208: }
1209:
1210: /**
1211: * Request the specified from port to a to port to produce a new link. This
1212: * method is executed when user drag a port to another port on the canvas.
1213: * It calls noNewLink whenever the link is not able to be create. If from
1214: * and to share the same parent, no link will be created. Finally, it
1215: * delagated the creation of the new to controller.
1216: *
1217: * @param from a from port
1218: * @param to a to port
1219: */
1220: public void newLink(JGoPort from, JGoPort to) {
1221: if (getCanvasController() == null) {
1222: super .newLink(from, to);
1223: }
1224:
1225: if (from.getParent() == to.getParent()) {
1226: noNewLink(from, to);
1227: return;
1228: }
1229:
1230: if (!(from.getParent() instanceof ICanvasMethoidNode)
1231: || !(to.getParent() instanceof ICanvasMethoidNode)) {
1232: noNewLink(from, to);
1233: return;
1234: }
1235:
1236: ICanvasFieldNode fromFieldNode = ((ICanvasMethoidNode) from
1237: .getParent()).getFieldNodeByConnectPointObject(from);
1238:
1239: ICanvasFieldNode toFieldNode = ((ICanvasMethoidNode) to
1240: .getParent()).getFieldNodeByConnectPointObject(to);
1241:
1242: if ((fromFieldNode == null) || (toFieldNode == null)) {
1243: noNewLink(from, to);
1244: return;
1245: }
1246:
1247: if (!(getCanvasController().handleAddLink(fromFieldNode,
1248: toFieldNode))) {
1249: noNewLink(from, to);
1250: }
1251: }
1252:
1253: /**
1254: * Handles the case where normally no new link would be created.
1255: * We override this method to check for the case where we may want to
1256: * pop up a dialog to allow the user to create a node.
1257: *
1258: * @param srcPort Source port
1259: * @param destPort Destination port
1260: */
1261: protected void noNewLink(JGoPort from, JGoPort to) {
1262: if (mDropLocation == null) {
1263: return;
1264: }
1265:
1266: Point viewLocation = mDropLocation;
1267: Point modelLocation = new Point(viewLocation);
1268: mDropLocation = null;
1269: this .convertViewToDoc(modelLocation);
1270:
1271: super .noNewLink(from, to);
1272:
1273: if (modelLocation == null) {
1274: return;
1275: }
1276:
1277: if (getCanvasController() == null) {
1278: return;
1279: }
1280:
1281: JGoPort sourcePort = (from != null) ? from : to;
1282: if (sourcePort == null) {
1283: return;
1284: }
1285:
1286: ICanvasFieldNode sourceFieldNode = ((ICanvasMethoidNode) sourcePort
1287: .getParent())
1288: .getFieldNodeByConnectPointObject(sourcePort);
1289:
1290: if (sourceFieldNode == null) {
1291: return;
1292: }
1293:
1294: getCanvasController().handleAddLink(sourceFieldNode,
1295: modelLocation, viewLocation, mDropAction);
1296: }
1297:
1298: public void doCancelMouse() {
1299: // Bug fix: prevents the new link dialog from popping up
1300: // sometimes if the drop location is outside of the canvas.
1301: mDropLocation = null;
1302: super .doCancelMouse();
1303: }
1304:
1305: public void onDrop(DropTargetDropEvent droptargetdropevent) {
1306: mDropLocation = droptargetdropevent.getLocation();
1307: mDropAction = droptargetdropevent.getDropAction();
1308: super .onDrop(droptargetdropevent);
1309: }
1310:
1311: /**
1312: * Handles key event
1313: *
1314: * @param evt Description of the Parameter
1315: */
1316: public void onKeyEvent(KeyEvent evt) {
1317: int t = evt.getKeyCode();
1318:
1319: if (t == KeyEvent.VK_DELETE) {
1320: if (getDocument().isModifiable()) {
1321: deleteSelection();
1322: }
1323: }
1324: }
1325:
1326: /**
1327: * Removes the nodes from the canvas
1328: *
1329: * @param nodes Description of the Parameter
1330: */
1331: public void removeNodes(Collection nodes) {
1332: final Iterator iter = nodes.iterator();
1333:
1334: SwingUtilities.invokeLater(new Runnable() {
1335: public void run() {
1336: while (iter.hasNext()) {
1337: JGoObject obj = (JGoObject) iter.next();
1338: if (obj instanceof ICanvasNodeToNodeLink) {
1339: mFilterNodeLinks.remove(obj);
1340: } else if (obj instanceof ICanvasNodeToTreeLink
1341: || obj instanceof ICanvasTreeToNodeLink
1342: || obj instanceof ICanvasTreeToTreeLink) {
1343: mFilterTreeNodeLink.remove(obj);
1344: }
1345:
1346: getDocument().removeObject(obj);
1347: }
1348: }
1349: });
1350: }
1351:
1352: /**
1353: * Selectes the node that repersent by the specified data object.
1354: *
1355: * @param dataObject the data object of the node.
1356: */
1357: public void selectNode(Object dataObject) {
1358: JGoDocument doc = getDocument();
1359: JGoListPosition pos = doc.getFirstObjectPos();
1360:
1361: while (pos != null) {
1362: JGoObject obj = doc.getObjectAtPos(pos);
1363: pos = doc.getNextObjectPosAtTop(pos);
1364:
1365: if (obj instanceof ICanvasNode) {
1366: ICanvasNode node = (ICanvasNode) obj;
1367:
1368: if (node.getDataObject() == dataObject) {
1369: this .selectObject(obj);
1370: // Ensure we have focus because otherwise key events don't get heard.
1371: return;
1372: }
1373: }
1374: }
1375: }
1376:
1377: public void onDragGestureRecognized(java.awt.dnd.DragGestureEvent e) {
1378: super .onDragGestureRecognized(e);
1379: }
1380:
1381: /**
1382: * Create the canvas node with the new group node added to this mapper.
1383: *
1384: * @param groupNode the new mapper group node.
1385: */
1386: protected void handleNewGroupNode(IMapperGroupNode groupNode) {
1387: if (!(groupNode instanceof IMethoidNode)) {
1388: return;
1389: }
1390:
1391: IMethoidNode methoidNode = (IMethoidNode) groupNode;
1392: ICanvasMethoidNode canvasMethoidNode = getCanvasObjectFactory()
1393: .createMethoidNode(methoidNode);
1394: addNode(canvasMethoidNode);
1395:
1396: IMapperNode node = methoidNode.getFirstNode();
1397:
1398: while (node != null) {
1399: handleNewNode(node);
1400: node = methoidNode.getNextNode(node);
1401: }
1402: groupNode.addPropertyChangeListener(mGroupNodeListener);
1403: }
1404:
1405: /**
1406: * Create the canvas node with the new node added to this mapper.
1407: *
1408: * @param node the new mapper node.
1409: */
1410: protected void handleNewNode(IMapperNode node) {
1411: if (node instanceof IMapperGroupNode) {
1412: handleNewGroupNode((IMapperGroupNode) node);
1413:
1414: return;
1415: }
1416:
1417: List links = node.getLinks();
1418: synchronized (mNewLinkList) {
1419: for (int i = 0; i < links.size(); i++) {
1420: if (!mNewLinkList.contains(links.get(i))) {
1421: mNewLinkList.add(links.get(i));
1422: }
1423: }
1424: }
1425:
1426: node.addPropertyChangeListener(mNodeLinkListener);
1427: }
1428:
1429: /**
1430: * Description of the Method
1431: *
1432: * @param node Description of the Parameter
1433: */
1434: protected void handleRemoveNode(IMapperNode node) {
1435: if (node instanceof IMethoidNode) {
1436: handleRemoveMethoidNode((IMethoidNode) node);
1437: return;
1438: } else {
1439: node.removePropertyChangeListener(mNodeLinkListener);
1440: }
1441: }
1442:
1443: /**
1444: * Description of the Method
1445: *
1446: * @param methoidNode Description of the Parameter
1447: */
1448: protected void handleRemoveMethoidNode(IMethoidNode methoidNode) {
1449: if (methoidNode instanceof IMethoidNode) {
1450: methoidNode
1451: .removePropertyChangeListener(mGroupNodeListener);
1452:
1453: for (IMapperNode childNode = methoidNode.getFirstNode(); childNode != null; childNode = methoidNode
1454: .getNextNode(childNode)) {
1455: handleRemoveNode(childNode);
1456: }
1457: }
1458:
1459: ICanvasMethoidNode canvasMethoidNode = findCanvasMethoidNode(methoidNode);
1460:
1461: if (canvasMethoidNode != null) {
1462: List removeNode = new ArrayList(1);
1463: removeNode.add(canvasMethoidNode);
1464: removeNodes(removeNode);
1465: }
1466: }
1467:
1468: /**
1469: * Reallocate the tree to tree link ports when scrolling.
1470: * Overrides JGoView.onScrollEvent.
1471: *
1472: * @param evt the scrolling event
1473: */
1474: protected void onScrollEvent(java.awt.event.AdjustmentEvent evt) {
1475:
1476: if (mFilterTreeNodeLink == null) {
1477: return;
1478: }
1479:
1480: int oldX = this .getViewPosition().x;
1481: int oldY = this .getViewPosition().y;
1482:
1483: // set the new view point
1484: super .onScrollEvent(evt);
1485:
1486: if (oldX != this .getViewPosition().x) {
1487: adjustTreeLinkPortsX();
1488: }
1489:
1490: if (oldY != this .getViewPosition().y) {
1491: adjustTreeLinkPortsY();
1492: }
1493:
1494: updateNodeToNodeLinks();
1495: }
1496:
1497: /**
1498: * Initialize canvas node with the specified view model. This method is call
1499: * whenever a new view model is loaded.
1500: *
1501: * @param viewModel the mapper view model to be read from.
1502: */
1503: protected void initializeCanvasNode(IMapperViewModel viewModel) {
1504: Collection nodes = viewModel.getNodes();
1505: Iterator iterator = nodes.iterator();
1506: Object node = null;
1507:
1508: synchronized (nodes) {
1509: while (iterator.hasNext()) {
1510: node = iterator.next();
1511:
1512: if (node instanceof IMapperNode) {
1513: handleNewNode((IMapperNode) node);
1514: }
1515: }
1516: }
1517: initializeNewLinks();
1518: }
1519:
1520: private void initializeNewLinks() {
1521: if (SwingUtilities.isEventDispatchThread()) {
1522: initializeNewLinksInST();
1523: } else {
1524: SwingUtilities.invokeLater(new Runnable() {
1525: public void run() {
1526: initializeNewLinksInST();
1527: }
1528: });
1529: }
1530: }
1531:
1532: private void initializeNewLinksInST() {
1533: IMapperViewModel model = getParentView().getViewModel();
1534: synchronized (mNewLinkList) {
1535: for (int i = 0; i < mNewLinkList.size(); i++) {
1536: final IMapperLink link = (IMapperLink) mNewLinkList
1537: .get(i);
1538:
1539: IMapperNode startTopLevelNode = findTopLevelNode(link
1540: .getStartNode());
1541: IMapperNode endToLevelNode = findTopLevelNode(link
1542: .getEndNode());
1543:
1544: if (startTopLevelNode != null && endToLevelNode != null
1545: && model.containsNode(startTopLevelNode)
1546: && model.containsNode(endToLevelNode)) {
1547:
1548: ICanvasLink canvasLink = getCanvasObjectFactory()
1549: .createLink(link);
1550: if (canvasLink != null) {
1551: addLink(canvasLink);
1552: mNewLinkList.remove(i);
1553: i--;
1554: } else {
1555: mLogger.log(Level.SEVERE,
1556: "Factory cannot create Canvas Link from mapper link: "
1557: + link.toString());
1558: }
1559: }
1560: }
1561: }
1562: }
1563:
1564: private IMapperNode findTopLevelNode(IMapperNode node) {
1565: while (node != null && node.getGroupNode() != null) {
1566: node = node.getGroupNode();
1567: }
1568: return node;
1569: }
1570:
1571: private void updateNodeToNodeLinks() {
1572: // this method could be called before
1573: // this class is instanated
1574: // some how JGoView constructor call onScrollEvent and call this method.
1575: if (mFilterNodeLinks == null) {
1576: return;
1577: }
1578: synchronized (mFilterNodeLinks) {
1579: for (int i = 0; i < mFilterNodeLinks.size(); i++) {
1580: AbstractCanvasLink link = (AbstractCanvasLink) mFilterNodeLinks
1581: .get(i);
1582: if (link.isDisplaying(getViewRect())) {
1583: link.calculateStroke();
1584: }
1585: }
1586: }
1587: }
1588:
1589: /**
1590: * Return the x coordination of a tree link from port.
1591: *
1592: * @return the x coordination of a tree link from port.
1593: */
1594: int getTreeLinkFromPortX() {
1595: return this .getViewPosition().x;
1596: }
1597:
1598: /**
1599: * Return the y coordination of the link ports in the specified node.
1600: *
1601: * @param node the node of all the links
1602: * @return the y coordination of the link port in the specified node.
1603: */
1604: int getTreeLinkPortY(IMapperNode node) {
1605: return node.getY()
1606: + AbstractCanvasLink.NodeYChangeListener.Y_AXIS_DIFF
1607: + getViewPosition().y;
1608: }
1609:
1610: /**
1611: * Return the x coordination of a tree link to port.
1612: *
1613: * @return the x coordination of a tree link to port.
1614: */
1615: int getTreeLinkToPortX() {
1616: return getTreeLinkFromPortX() + this .getExtentSize().width;
1617: }
1618:
1619: /**
1620: * Adjust tree links in this canvas when size or view size change.
1621: */
1622: private void adjustTreeLinkPortsX() {
1623: final int fromPortX = getTreeLinkFromPortX();
1624: final int toPortX = getTreeLinkToPortX();
1625:
1626: SwingUtilities.invokeLater(new Runnable() {
1627: public void run() {
1628: int i = 0;
1629: Object filterLink = null;
1630: while (i < mFilterTreeNodeLink.size()) {
1631: synchronized (mFilterTreeNodeLink) {
1632: if (mFilterTreeNodeLink.size() <= i) {
1633: break;
1634: }
1635: filterLink = mFilterTreeNodeLink.get(i++);
1636: }
1637:
1638: if (filterLink instanceof AbstractCanvasLink) {
1639: final AbstractCanvasLink canvasLink = (AbstractCanvasLink) filterLink;
1640:
1641: if (canvasLink.getMapperLink().getStartNode() instanceof IMapperTreeNode) {
1642:
1643: JGoPort fromPort = canvasLink.getFromPort();
1644: fromPort.setLeft(fromPortX);
1645: }
1646:
1647: if (canvasLink.getMapperLink().getEndNode() instanceof IMapperTreeNode) {
1648:
1649: JGoPort toPort = canvasLink.getToPort();
1650: toPort.setLeft(toPortX);
1651: }
1652: }
1653: }
1654: }
1655: });
1656: }
1657:
1658: /**
1659: * Adjust tree links in this canvas when size or view size change.
1660: */
1661: private void adjustTreeLinkPortsY() {
1662:
1663: SwingUtilities.invokeLater(new Runnable() {
1664: public void run() {
1665:
1666: int i = 0;
1667: Object linkObj = null;
1668:
1669: while (i < mFilterTreeNodeLink.size()) {
1670:
1671: synchronized (mFilterTreeNodeLink) {
1672: if (i >= mFilterTreeNodeLink.size()) {
1673: break;
1674: }
1675: linkObj = mFilterTreeNodeLink.get(i++);
1676: }
1677:
1678: if (linkObj instanceof AbstractCanvasLink) {
1679: final AbstractCanvasLink canvasLink = (AbstractCanvasLink) linkObj;
1680:
1681: if (canvasLink.getMapperLink().getStartNode() instanceof IMapperTreeNode) {
1682: JGoPort fromPort = canvasLink.getFromPort();
1683: fromPort.setTop(getTreeLinkPortY(canvasLink
1684: .getMapperLink().getStartNode()));
1685: }
1686:
1687: if (canvasLink.getMapperLink().getEndNode() instanceof IMapperTreeNode) {
1688: JGoPort toPort = canvasLink.getToPort();
1689: toPort.setTop(getTreeLinkPortY(canvasLink
1690: .getMapperLink().getEndNode()));
1691: }
1692: }
1693: }
1694: }
1695: });
1696: }
1697:
1698: /**
1699: * Print out the JGoDocument debugging information.
1700: */
1701: private void debugDoc() {
1702: JGoListPosition pos = this .getDocument().getFirstObjectPos();
1703:
1704: for (; pos != null; pos = this .getDocument().getNextObjectPos(
1705: pos)) {
1706: JGoObject obj = this .getDocument().getObjectAtPos(pos);
1707: }
1708: }
1709:
1710: /**
1711: * We need to determine what object exists on the entire canvas
1712: * at the specified mouse location. If we find a methoid node, then
1713: * we need to ask it for the tooltip text within itself (which iterates
1714: * through its contained field nodes).
1715: */
1716: public String getToolTipText(MouseEvent mouseevent) {
1717: if (!isMouseEnabled())
1718: return null;
1719: Point point = mouseevent.getPoint();
1720: convertViewToDoc(point);
1721: for (Object obj = pickDocObject(point, false); obj != null; obj = ((JGoObject) (obj))
1722: .getParent()) {
1723: String s = null;
1724: if (obj instanceof BasicCanvasMethoidNode) {
1725: s = ((BasicCanvasMethoidNode) obj)
1726: .getToolTipText(point);
1727: } else {
1728: s = ((JGoObject) obj).getToolTipText();
1729: }
1730: if (s != null)
1731: return s;
1732: }
1733:
1734: return null;
1735: }
1736:
1737: public void addCanvasMouseListener(ICanvasMouseListener listener) {
1738: synchronized (mMouseListeners) {
1739: mMouseListeners.add(listener);
1740: }
1741: }
1742:
1743: public void removeCanvasMouseListener(ICanvasMouseListener listener) {
1744: synchronized (mMouseListeners) {
1745: mMouseListeners.remove(listener);
1746: }
1747: }
1748:
1749: public boolean fireMouseEvent(int event, ICanvasMouseData data) {
1750: boolean result = false;
1751: List list = new LinkedList();
1752: synchronized (mMouseListeners) {
1753: list.addAll(mMouseListeners);
1754: }
1755: Iterator iter = list.iterator();
1756: while (iter.hasNext()) {
1757: ICanvasMouseListener l = (ICanvasMouseListener) iter.next();
1758: switch (event) {
1759: case MOUSE_CLICK:
1760: if (l.doMouseClick(data)) {
1761: result = true;
1762: }
1763: break;
1764: case MOUSE_DBLCLICK:
1765: if (l.doMouseDblClick(data)) {
1766: result = true;
1767: }
1768: break;
1769: case MOUSE_PRESS:
1770: if (l.doMouseDown(data)) {
1771: result = true;
1772: }
1773: break;
1774: case MOUSE_RELEASE:
1775: if (l.doMouseUp(data)) {
1776: result = true;
1777: }
1778: break;
1779: case MOUSE_MOVE:
1780: if (l.doMouseMove(data)) {
1781: result = true;
1782: }
1783: break;
1784: }
1785: }
1786: return result;
1787: }
1788:
1789: public JGoSelection createDefaultSelection() {
1790: return new PortSelection(this ) {
1791: public JGoObject selectObject(JGoObject obj) {
1792: SwingUtilities.invokeLater(new Runnable() {
1793: public void run() {
1794: requestFocus();
1795: }
1796: });
1797:
1798: getDocument().bringObjectToFront(obj);
1799: return super .selectObject(obj);
1800: }
1801: };
1802: }
1803:
1804: public void autoscroll(Point location) {
1805: // do nothing... we don't want the canvas to autoscroll
1806: }
1807:
1808: private static class HoverPort {
1809: private BasicCanvasFieldNode mFieldNode;
1810: private DrawPort mDrawPort;
1811:
1812: public HoverPort(BasicCanvasFieldNode field) {
1813: mFieldNode = field;
1814: mDrawPort = field.getDrawPort();
1815: }
1816:
1817: public HoverPort(DrawPort drawPort) {
1818: mFieldNode = drawPort.getFieldNode();
1819: mDrawPort = drawPort;
1820: }
1821:
1822: public void set(boolean isActivated) {
1823: mDrawPort.setIsActivated(isActivated);
1824: mDrawPort.setIsHovering(true);
1825: mFieldNode.setIsHovering(true);
1826: mFieldNode.layoutPorts();
1827: }
1828:
1829: public void unset() {
1830: mDrawPort.setIsActivated(false);
1831: mDrawPort.setIsHovering(false);
1832: mFieldNode.setIsHovering(false);
1833: mFieldNode.layoutPorts();
1834: }
1835: }
1836:
1837: /**
1838: * This class listens on the change of the size of this canvas to relocate
1839: * the ports that connect to tree node.
1840: *
1841: * @author sleong
1842: * @created December 4, 2002
1843: */
1844: private class CanvasSizeListener extends ComponentAdapter {
1845: /**
1846: * Re-adjust tree link ports x coordination when this canvas resize.
1847: *
1848: * @param e the ComponentEvent
1849: */
1850: public void componentResized(ComponentEvent e) {
1851: adjustTreeLinkPortsX();
1852: updateNodeToNodeLinks();
1853: }
1854: }
1855:
1856: /**
1857: * This class listens on the change of each mapper node of the view model
1858: * and the node inside the group node for link changes.
1859: *
1860: * @author sleong
1861: * @created December 4, 2002
1862: */
1863: private class NodeLinkListener implements PropertyChangeListener {
1864: /**
1865: * the canvas of the node it is listenning on.
1866: */
1867: private ICanvasView mCanvasView;
1868:
1869: /**
1870: * Construct a NodeLinkListener with the specified canvas.
1871: *
1872: * @param canvasView the canvas
1873: */
1874: private NodeLinkListener(ICanvasView canvasView) {
1875: mCanvasView = canvasView;
1876: }
1877:
1878: /**
1879: * Execute when a change of a mapper node. This method handles the add
1880: * and remove link event of a node.
1881: *
1882: * @param e the PropertyChangeEvent event.
1883: */
1884: public void propertyChange(PropertyChangeEvent e) {
1885: if (e.getPropertyName().equals(IMapperNode.LINK_ADDED)) {
1886: if (e.getNewValue() instanceof IMapperLink
1887: && (e.getSource() == ((IMapperLink) e
1888: .getNewValue()).getStartNode())) {
1889: mNewLinkList.add((IMapperLink) e.getNewValue());
1890: initializeNewLinks();
1891: }
1892: } else if (e.getPropertyName().equals(
1893: IMapperNode.LINK_REMOVED)) {
1894: if (e.getOldValue() instanceof IMapperLink) {
1895: IMapperLink link = (IMapperLink) e.getOldValue();
1896:
1897: ICanvasLink canvasLink = getCanvasLinkByDataObject(link);
1898:
1899: if (canvasLink != null) {
1900: List removeLink = new ArrayList(1);
1901: removeLink.add(canvasLink);
1902: mCanvasView.removeNodes(removeLink);
1903: }
1904: }
1905: }
1906: }
1907: }
1908:
1909: /**
1910: * This class listen on the change of view model.
1911: *
1912: * @author sleong
1913: * @created December 4, 2002
1914: */
1915: private class ViewModelChangeListener implements
1916: PropertyChangeListener {
1917: /**
1918: * Add/Remove canvas objects when there is a link changed on the link
1919: * model.
1920: *
1921: * @param e the PropertyChangeEvent
1922: */
1923: public void propertyChange(PropertyChangeEvent e) {
1924: if (e.getPropertyName().equals(IMapperViewModel.NODE_ADDED)) {
1925: handleNewNode((IMapperNode) e.getNewValue());
1926: initializeNewLinks();
1927: } else if (e.getPropertyName().equals(
1928: IMapperViewModel.NODE_REMOVED)) {
1929: handleRemoveNode((IMapperNode) e.getOldValue());
1930: }
1931: }
1932: }
1933:
1934: /**
1935: * Provides grouop node add / remove nodes listener functions.
1936: *
1937: * @author sleong
1938: * @created January 29, 2003
1939: */
1940: private class GroupNodeListener implements PropertyChangeListener {
1941:
1942: /**
1943: * If new node added to the group node, add listener for new link event.
1944: * If node removed from the group node, remove new link listener.
1945: *
1946: * @param e Description of the Parameter
1947: */
1948: public void propertyChange(PropertyChangeEvent e) {
1949: if (e.getPropertyName().equals(
1950: IMapperGroupNode.NODE_INSERTED)) {
1951: handleNewNode((IMapperNode) e.getNewValue());
1952: initializeNewLinks();
1953: } else if (e.getPropertyName().equals(
1954: IMapperGroupNode.NODE_REMOVED)) {
1955: handleRemoveNode((IMapperNode) e.getOldValue());
1956: }
1957: }
1958: }
1959: }
|