protected void removeFromDiagramImpl() { Object o = getOwner(); if (o != null) { removeElementListener(o); } ArgoEventPump.removeListener(this); Iterator it = getPathItemFigs().iterator(); while (it.hasNext()) { Fig fig = (Fig) it.next(); fig.removeFromDiagram(); } /* TODO: MVW: Why the next action? * Deleting a fig from 1 diagram should not influence others! * */ // GEF does not take into account the multiple diagrams we have // therefore we loop through our diagrams and delete each and every // occurence on our own it = ProjectManager.getManager().getCurrentProject().getDiagrams().iterator(); while (it.hasNext()) { ArgoDiagram diagram = (ArgoDiagram) it.next(); diagram.damage(); } /* TODO: MVW: Should we not call damage() * for diagrams AFTER the next step? */ super.removeFromDiagram(); }
private void constructFigs(int x, int y, int w, int h) { bigPort = new FigRect(x, y, w, h, LINE_COLOR, FILL_COLOR); bigPort.setFilled(true); setFilled(true); bigPort.setLineWidth(0); setLineWidth(0); addFig(bigPort); }
/** * If the selected Fig is a FigAssociation (an edge) then convert it to a FigNodeAssociation. * * @param fig the select end Fig * @return the fig converted to a FigNode */ private FigNode convertToFigNode(Fig fig) { if (fig instanceof FigEdgePort) { fig = fig.getGroup(); } if (!(fig instanceof FigAssociation)) { return (FigNode) fig; } final FigAssociation figAssociation = (FigAssociation) fig; final int x = figAssociation.getEdgePort().getX(); final int y = figAssociation.getEdgePort().getY(); final Object association = fig.getOwner(); final FigNode originalEdgePort = figAssociation.getEdgePort(); // Detach any edges (such as comment edges) already attached // to the FigAssociation before the FigAssociation is removed. // They'll later be re-attached to the new FigNodeAssociation final Collection<FigEdge> existingEdges = originalEdgePort.getEdges(); for (FigEdge edge : existingEdges) { originalEdgePort.removeFigEdge(edge); } figAssociation.removeFromDiagram(); // Create the new FigNodeAssociation and locate it. final MutableGraphModel gm = (MutableGraphModel) editor.getGraphModel(); gm.addNode(association); final LayerPerspective lay = (LayerPerspective) editor.getLayerManager().getActiveLayer(); final List associationFigs = lay.presentationsFor(association); associationFigs.remove(figAssociation); final FigNodeAssociation figNode = (FigNodeAssociation) associationFigs.get(0); figNode.setLocation(x - figNode.getWidth() / 2, y - figNode.getHeight() / 2); editor.add(figNode); editor.getSelectionManager().deselectAll(); // Add the association ends to the graph model final Collection<Object> associationEnds = Model.getFacade().getConnections(association); for (Object associationEnd : associationEnds) { gm.addEdge(associationEnd); } // Add the edges (such as comment edges) that were on the old // FigAssociation to our new FigNodeAssociation and make sure they are // positioned correctly. for (FigEdge edge : existingEdges) { if (edge.getDestFigNode() == originalEdgePort) { edge.setDestFigNode(figNode); edge.setDestPortFig(figNode); } if (edge.getSourceFigNode() == originalEdgePort) { edge.setSourceFigNode(figNode); edge.setSourcePortFig(figNode); } } figNode.updateEdges(); return figNode; }
/** @see org.tigris.gef.presentation.Fig#hit(java.awt.Rectangle) */ public boolean hit(Rectangle r) { // Check if labels etc have been hit // Apparently GEF does require PathItems to be "annotations" // which ours aren't, so until that is resolved... Iterator it = getPathItemFigs().iterator(); while (it.hasNext()) { Fig f = (Fig) it.next(); if (f.hit(r)) return true; } return super.hit(r); }
/** Change the line. */ public void setTargetLine() { Fig target = getPanelTarget(); Object c = lineField.getSelectedItem(); if (target == null || c == null) { return; } if (c instanceof Color) { target.setLineColor((Color) c); } target.setLineWidth((c instanceof Color) ? 1 : 0); target.endTrans(); }
/** Change the fill. */ public void setTargetFill() { Fig target = getPanelTarget(); Object c = fillField.getSelectedItem(); if (target == null || c == null) { return; } if (c instanceof Color) { target.setFillColor((Color) c); } target.setFilled(c instanceof Color); target.endTrans(); }
/** * Add a classier to the current diagram. * * @param classifier The new class or interface to add to the editor. * @param minimise minimise the class fig by hiding compartments (of attributes and operations) */ private void addClassifier(Object classifier, boolean minimise) { String name = Model.getFacade().getName(classifier); // if the classifier is not in the current diagram, add it: if (currentGM.canAddNode(classifier)) { FigClassifierBox newFig; if (Model.getFacade().isAClass(classifier)) { newFig = new FigClass(currentGM, classifier); } else if (Model.getFacade().isAInterface(classifier)) { newFig = new FigInterface(currentGM, classifier); } else { return; } /* * The following calls are ORDER DEPENDENT. Not sure why, but the * layer add must come before the model add or we'll end up with * duplicate figures in the diagram. - tfm */ currentLayer.add(newFig); currentGM.addNode(classifier); currentLayer.putInPosition(newFig); newFig.setOperationsVisible(!minimise); if (Model.getFacade().isAClass(classifier)) { ((FigClass) newFig).setAttributesVisible(!minimise); } newFig.setSize(newFig.getMinimumSize()); } else { // the class is in the diagram // so we are on a second pass, // find the fig for this class can update its visible state. FigClassifierBox existingFig = null; List figs = currentLayer.getContentsNoEdges(); for (int i = 0; i < figs.size(); i++) { Fig fig = (Fig) figs.get(i); if (classifier == fig.getOwner()) { existingFig = (FigClassifierBox) fig; } } existingFig.renderingChanged(); } // add edges // for a 2-pass r.e. process we might have already added the // class but not its edges currentGM.addNodeRelatedEdges(classifier); }
/** * Main constructor for a {@link FigClass}. * * <p>Parent {@link FigNodeModelElement} will have created the main box {@link #getBigPort()} and * its name {@link #getNameFig()} and stereotype (@link #getStereotypeFig()}. This constructor * creates a box for the attributes and operations. * * <p>The properties of all these graphic elements are adjusted appropriately. The main boxes are * all filled and have outlines. * * <p>For reasons I don't understand the stereotype is created in a box with lines. So we have to * created a blanking rectangle to overlay the bottom line, and avoid four compartments showing. * * <p>There is some complex logic to allow for the possibility that stereotypes may not be * displayed (unlike operations and attributes this is not a standard thing for UML). Some care is * needed to ensure that additional space is not added, each time a stereotyped class is loaded. * * <p>There is a particular problem when loading diagrams with stereotyped classes. Because we * create a FigClass indicating the stereotype is not displayed, we then add extra space for such * classes when they are first rendered. This ought to be fixed by correctly saving the class * dimensions, but that needs more work. The solution here is to use a simple flag to indicate the * FigClass has just been created. * * <p><em>Warning</em>. Much of the graphics positioning is hard coded. The overall figure is * placed at location (10,10). The name compartment (in the parent {@link FigNodeModelElement} is * 21 pixels high. The stereotype compartment is created 15 pixels high in the parent, but we * change it to 19 pixels, 1 more than ({@link #STEREOHEIGHT} here. The attribute and operations * boxes are created at 19 pixels, 2 more than {@link #ROWHEIGHT}. * * <p>CAUTION: This constructor (with no arguments) is the only one that does * enableSizeChecking(false), all others must set it true. This is because this constructor is the * only one called when loading a project. In this case, the parsed size must be maintained. * * <p> */ public FigClass() { getBigPort().setLineWidth(0); getBigPort().setFillColor(Color.white); // Attributes inside. First one is the attribute box itself. attributesFigCompartment = new FigAttributesCompartment(10, 30, 60, ROWHEIGHT + 2); // The operations compartment is built in the ancestor FigClassifierBox // Set properties of the stereotype box. Make it 1 pixel higher than // before, so it overlaps the name box, and the blanking takes out both // lines. Initially not set to be displayed, but this will be changed // when we try to render it, if we find we have a stereotype. getStereotypeFig().setFilled(false); getStereotypeFig().setHeight(STEREOHEIGHT + 1); // +1 to have 1 pixel overlap with getNameFig() getStereotypeFig().setVisible(true); borderFig = new FigEmptyRect(10, 10, 0, 0); borderFig.setLineWidth(1); borderFig.setLineColor(Color.black); getStereotypeFig().setLineWidth(0); // Mark this as newly created. This is to get round the problem with // creating figs for loaded classes that had stereotypes. They are // saved with their dimensions INCLUDING the stereotype, but since we // pretend the stereotype is not visible, we add height the first time // we render such a class. This is a complete fudge, and really we // ought to address how class objects with stereotypes are saved. But // that will be hard work. newlyCreated = true; // Put all the bits together, suppressing bounds calculations until // we're all done for efficiency. enableSizeChecking(false); setSuppressCalcBounds(true); addFig(getBigPort()); addFig(getStereotypeFig()); addFig(getNameFig()); addFig(operationsFig); addFig(attributesFigCompartment); addFig(borderFig); setSuppressCalcBounds(false); // Set the bounds of the figure to the total of the above (hardcoded) setBounds(10, 10, 60, 22 + 2 * ROWHEIGHT); }
/** * A version of GEF's presentationFor() method which * * @param element ModelElement to return presentation for * @return the Fig representing the presentation */ private Fig getNoEdgePresentationFor(Object element) { if (element == null) { throw new IllegalArgumentException("Can't search for a null owner"); } List contents = getLayer().getContentsNoEdges(); int figCount = contents.size(); for (int figIndex = 0; figIndex < figCount; ++figIndex) { Fig fig = (Fig) contents.get(figIndex); if (fig.getOwner() == element) { return fig; } } throw new IllegalStateException( "Can't find a FigNode representing " + Model.getFacade().getName(element)); }
@Override public Object getOwner() { if (super.getOwner() != null) { return super.getOwner(); } Fig group = this; while (group != null && !(group instanceof FigEdge)) { group = group.getGroup(); } if (group == null) { return null; } else { return group.getOwner(); } }
/* * @see org.tigris.gef.presentation.Fig#setLineWidth(int) */ @Override public void setLineWidth(int width) { // Miss out the text fix, this should have no line for (int i = HEAD_POSN; i < RIGHT_LEG_POSN; i++) { Fig f = getFigAt(i); if (f != null) { f.setLineWidth(width); } } getFigAt(HEAD_POSN).setLineWidth(width); getFigAt(BODY_POSN).setLineWidth(width); getFigAt(ARMS_POSN).setLineWidth(width); getFigAt(LEFT_LEG_POSN).setLineWidth(width); getFigAt(RIGHT_LEG_POSN).setLineWidth(width); }
/** @see org.tigris.gef.presentation.Fig#setEnclosingFig(org.tigris.gef.presentation.Fig) */ public void setEnclosingFig(Fig encloser) { if (encloser == null || (encloser != null && !Model.getFacade().isAInstance(encloser.getOwner()))) { super.setEnclosingFig(encloser); } if (!(Model.getFacade().isAModelElement(getOwner()))) return; if (encloser != null && (Model.getFacade().isAComponent(encloser.getOwner()))) { Object component = /*(MComponent)*/ encloser.getOwner(); Object in = /*(MInterface)*/ getOwner(); Model.getCoreHelper().setContainer(resident, component); Model.getCoreHelper().setResident(resident, in); } else { Model.getCoreHelper().setContainer(resident, null); Model.getCoreHelper().setResident(resident, null); } }
private void addFig( final Fig f, final DefaultMutableTreeNode rootNode, final boolean includeEncloser) { // Build the selected Fig first and then iterate up through // its enclosers building those also. for (Fig fig = f; fig != null; fig = includeEncloser ? fig.getEnclosingFig() : null) { DefaultMutableTreeNode figNode = new DefaultMutableTreeNode(getDescr(fig)); rootNode.add(figNode); buildTree(fig, figNode); // For a classifier role on a sequence diagram // show its message nodes if (fig instanceof FigClassifierRole) { MessageNodeBuilder.addNodeTree(rootNode, (FigClassifierRole) fig); } } }
protected void applyOffsetAmount(Point p1, Point p2, int offset, Point res) { // slope of the line we're finding the normal to // is slope, and the normal is the negative reciprocal // slope is (p1.y - p2.y) / (p1.x - p2.x) // so recip is - (p1.x - p2.x) / (p1.y - p2.y) int recipnumerator = (p1.x - p2.x) * -1; int recipdenominator = (p1.y - p2.y); if (recipdenominator == 0 && recipnumerator == 0) return; // find the point offset on the line that gives a // correct offset double len = Math.sqrt(recipnumerator * recipnumerator + recipdenominator * recipdenominator); int dx = (int) ((recipdenominator * offset) / len); int dy = (int) ((recipnumerator * offset) / len); res.x += Math.abs(dx); res.y -= Math.abs(dy); int width = itemFig.getWidth() / 2; if (recipnumerator != 0) { double slope = (double) recipdenominator / (double) recipnumerator; double factor = tanh(slope); res.x += (Math.abs(factor) * width); } else { res.x += width; } }
public void setEnclosingFig(Fig encloser) { if (encloser == getEncloser()) { return; } if (encloser == null || (encloser != null && !Model.getFacade().isAInstance(encloser.getOwner()))) { super.setEnclosingFig(encloser); } if (!(Model.getFacade().isAUMLElement(getOwner()))) { return; } if (encloser != null && (Model.getFacade().isAComponent(encloser.getOwner()))) { moveIntoComponent(encloser); super.setEnclosingFig(encloser); } }
private void fixModel() { Fig sourceFig = getSourceFigNode(); Fig destFig = getDestFigNode(); Object source = sourceFig.getOwner(); Object dest = destFig.getOwner(); LOG.error( "Missing Generalization for figure in PGML -" + " attempting to recreate between " + source + " and " + dest); if (Model.getFacade().isAGeneralizableElement(source) && Model.getFacade().isAGeneralizableElement(dest)) { setOwner(Model.getCoreFactory().buildGeneralization(source, dest)); } }
/* * @see java.awt.event.ItemListener#itemStateChanged(java.awt.event.ItemEvent) */ public void itemStateChanged(ItemEvent e) { Object src = e.getSource(); Fig target = getPanelTarget(); if (e.getStateChange() == ItemEvent.SELECTED && target != null) { if (src == fillField) { if (e.getItem() == CUSTOM_ITEM) { handleCustomColor(fillField, "Custom Fill Color", target.getFillColor()); } setTargetFill(); } else if (src == lineField) { if (e.getItem() == CUSTOM_ITEM) { handleCustomColor(lineField, "Custom Line Color", target.getLineColor()); } setTargetLine(); } } }
/** * The minimum width is the minimum width of the child with the widest miniumum width. The minimum * height is the total minimum height of all child figs plus a 2 pixel padding. * * @return the minimum width */ @Override public Dimension getMinimumSize() { int minWidth = 0; int minHeight = 0; for (Fig fig : (Collection<Fig>) getFigs()) { if (fig.isVisible() && fig != getBigPort()) { int fw = fig.getMinimumSize().width; if (fw > minWidth) { minWidth = fw; } minHeight += fig.getMinimumSize().height; } } minHeight += 2; // 2 Pixel padding after compartment return new Dimension(minWidth, minHeight); }
/** generate the notation for the stereotype and stuff it into the text Fig */ protected void updateStereotypeText() { if (getOwner() == null) { return; } Object modelElement = getOwner(); stereotypeFig.setOwner(modelElement); ((FigStereotypesCompartment) stereotypeFig).populate(); }
/** * Updates the classifiers the edge is attached to. * * <p>Calls a helper method (layoutThisToSelf) to avoid this edge disappearing if the new source * and dest are the same node. * * @return boolean whether or not the update was sucessful */ protected boolean updateClassifiers() { Object owner = getOwner(); if (owner == null || getLayer() == null) { LOG.error("The FigEdge has no owner or its layer is null"); return false; } Object newSource = getSource(); Object newDest = getDestination(); Fig currentSourceFig = getSourceFigNode(); Fig currentDestFig = getDestFigNode(); Object currentSource = null; Object currentDestination = null; if (currentSourceFig != null && currentDestFig != null) { currentSource = currentSourceFig.getOwner(); currentDestination = currentDestFig.getOwner(); } if (newSource != currentSource || newDest != currentDestination) { Fig newSourceFig = getNoEdgePresentationFor(newSource); Fig newDestFig = getNoEdgePresentationFor(newDest); if (newSourceFig != currentSourceFig) { setSourceFigNode((FigNode) newSourceFig); setSourcePortFig(newSourceFig); } if (newDestFig != currentDestFig) { setDestFigNode((FigNode) newDestFig); setDestPortFig(newDestFig); } ((FigNode) newSourceFig).updateEdges(); ((FigNode) newDestFig).updateEdges(); calcBounds(); // adapted from SelectionWButtons from line 280 // calls a helper method to avoid this edge disappearing // if the new source and dest are the same node. if (newSourceFig == newDestFig) { layoutThisToSelf(); } } return true; }
/** * Grabs label to begin movement. Turns cursor into a hand. * * @param me The mouse event to process. * @override * @see org.tigris.gef.base.ModeImpl#mousePressed(java.awt.event.MouseEvent) */ public void mousePressed(MouseEvent me) { Point clickPoint = me.getPoint(); Fig underMouse = editor.hit(clickPoint); if (underMouse instanceof FigEdge) { List<Fig> figList = ((FigEdge) underMouse).getPathItemFigs(); for (Fig fig : figList) { if (fig.contains(clickPoint)) { // Consume to stop other modes from trying to take over me.consume(); dragFig = fig; dragBasePoint = fig.getCenter(); deltax = clickPoint.x - dragBasePoint.x; deltay = clickPoint.y - dragBasePoint.y; figEdge = (FigEdge) underMouse; break; } } } }
/** * If there are interfaces that are not inside a component the returned ListSet is not null. Then * in the ListSet are the UMLDeploymentDiagram and all FigInterfaces with no enclosing * FigComponent * * @param dd the diagram to check * @return the set of offenders */ public ListSet computeOffenders(UMLDeploymentDiagram dd) { Collection figs = dd.getLayer().getContents(); ListSet offs = null; Iterator figIter = figs.iterator(); while (figIter.hasNext()) { Object obj = figIter.next(); if (!(obj instanceof FigInterface)) continue; FigInterface fi = (FigInterface) obj; Fig enclosing = fi.getEnclosingFig(); if (enclosing == null || (!(Model.getFacade().isAComponent(enclosing.getOwner())))) { if (offs == null) { offs = new ListSet(); offs.add(dd); } offs.add(fi); } } return offs; }
/** * Create an edge of the given type and connect it to the given nodes. * * @param graphModel the graph model in which to create the connection element * @param edgeType the UML object type of the connection * @param sourceFig the FigNode for the source element * @param destFig the FigNode for the destination element * @return The FigEdge representing the newly created model element */ @Override protected FigEdge buildConnection( MutableGraphModel graphModel, Object edgeType, Fig sourceFig, Fig destFig) { try { Object associationEnd = Model.getUmlFactory() .buildConnection( edgeType, sourceFig.getOwner(), null, destFig.getOwner(), null, null, null); final FigNode sourceFigNode = convertToFigNode(sourceFig); final FigNode destFigNode = convertToFigNode(destFig); graphModel.addEdge(associationEnd); setNewEdge(associationEnd); // Calling connect() will add the edge to the GraphModel and // any LayerPersectives on that GraphModel will get a // edgeAdded event and will add an appropriate FigEdge // (determined by the GraphEdgeRenderer). if (getNewEdge() != null) { sourceFigNode.damage(); destFigNode.damage(); Layer lay = editor.getLayerManager().getActiveLayer(); FigEdge fe = (FigEdge) lay.presentationFor(getNewEdge()); _newItem.setLineColor(Color.black); fe.setFig(_newItem); fe.setSourcePortFig(sourceFigNode); fe.setSourceFigNode(sourceFigNode); fe.setDestPortFig(destFigNode); fe.setDestFigNode(destFigNode); return fe; } else { return null; } } catch (IllegalModelElementConnectionException e) { // We have already confirmed the connection is valid return null; } }
/** * Sets the bounds, but the size will be at least the one returned by {@link #getMinimumSize()}, * unless checking of size is disabled. * * <p>If the required height is bigger, then the additional height is equally distributed among * all figs (i.e. compartments), such that the cumulated height of all visible figs equals the * demanded height * * <p>. * * <p>Some of this has "magic numbers" hardcoded in. In particular there is a knowledge that the * minimum height of a name compartment is 21 pixels. * * <p> * * @param x Desired X coordinate of upper left corner * @param y Desired Y coordinate of upper left corner * @param w Desired width of the FigClass * @param h Desired height of the FigClass */ protected void setBoundsImpl(final int x, final int y, final int w, final int h) { Rectangle oldBounds = getBounds(); // set bounds of big box getBigPort().setBounds(x, y, w, h); borderFig.setBounds(x, y, w, h); // Save our old boundaries (needed later), and get minimum size // info. "whitespace" will be used to maintain a running calculation of our // size at various points. final int whitespace = h - getMinimumSize().height; getNameFig().setLineWidth(0); getNameFig().setLineColor(Color.red); int currentHeight = 0; if (getStereotypeFig().isVisible()) { int stereotypeHeight = getStereotypeFig().getMinimumSize().height; getStereotypeFig().setBounds(x, y, w, stereotypeHeight); currentHeight = stereotypeHeight; } int nameHeight = getNameFig().getMinimumSize().height; getNameFig().setBounds(x, y + currentHeight, w, nameHeight); currentHeight += nameHeight; if (isAttributesVisible()) { int attributesHeight = getAttributesFig().getMinimumSize().height; if (isOperationsVisible()) { attributesHeight += whitespace / 2; } getAttributesFig().setBounds(x, y + currentHeight, w, attributesHeight); currentHeight += attributesHeight; } if (isOperationsVisible()) { int operationsY = y + currentHeight; int operationsHeight = (h + y) - operationsY - 1; if (operationsHeight < getOperationsFig().getMinimumSize().height) { operationsHeight = getOperationsFig().getMinimumSize().height; } getOperationsFig().setBounds(x, operationsY, w, operationsHeight); } // Now force calculation of the bounds of the figure, update the edges // and trigger anyone who's listening to see if the "bounds" property // has changed. calcBounds(); updateEdges(); firePropChange("bounds", oldBounds, getBounds()); }
/** * Change the bounds of the target fig. Called whenever the bounds box is edited. * * <p>Format of the bounds is four integers representing x, y, width and height separated by * spaces or commas. An empty field is treated as no change and leading and trailing spaces are * ignored. * * <p><em>Note</em>. There is a note in the old code that more work might be needed, because this * could change the graph model. I don't see how that could ever be. */ protected void setTargetBBox() { Fig target = getPanelTarget(); // Can't do anything if we don't have a fig. if (target == null) { return; } // Parse the boundary box text. Null is // returned if it is empty or // invalid, which causes no change. Otherwise we tell // GEF we are making // a change, make the change and tell GEF we've // finished. Rectangle bounds = parseBBox(); if (bounds == null) { return; } if (!target.getBounds().equals(bounds)) { target.setBounds(bounds.x, bounds.y, bounds.width, bounds.height); target.endTrans(); } }
/** * Handle a refresh of the style panel after the fig has moved. * * <p><em>Warning</em>. There is a circular trap here. Editing the boundary box will also trigger * a refresh, and so we reset the boundary box, which causes funny behaviour (the cursor keeps * jumping to the end of the text). * * <p>The solution is to not reset the boundary box field if the boundaries have not changed. * * <p> */ public void refresh() { Fig target = getPanelTarget(); if (target instanceof FigEdgeModelElement) { hasEditableBoundingBox(false); } else { hasEditableBoundingBox(true); } if (target == null) return; // The boundary box as held in the target fig, and as listed in // the // boundary box style field (null if we don't have anything // valid) Rectangle figBounds = target.getBounds(); Rectangle styleBounds = parseBBox(); // Only reset the text if the two are not the same (i.e the fig // has // moved, rather than we've just edited the text, when // setTargetBBox() // will have made them the same). Note that styleBounds could // be null, // so we do the test this way round. if (!(figBounds.equals(styleBounds))) { bboxField.setText( figBounds.x + "," + figBounds.y + "," + figBounds.width + "," + figBounds.height); } // Change the fill colour if (target.getFilled()) { Color c = target.getFillColor(); fillField.setSelectedItem(c); if (c != null && !fillField.getSelectedItem().equals(c)) { fillField.insertItemAt(c, fillField.getItemCount() - 1); fillField.setSelectedItem(c); } } else { fillField.setSelectedIndex(0); } // Change the line colour if (target.getLineWidth() > 0) { Color c = target.getLineColor(); lineField.setSelectedItem(c); if (c != null && !lineField.getSelectedItem().equals(c)) { lineField.insertItemAt(c, lineField.getItemCount() - 1); lineField.setSelectedItem(c); } } else { lineField.setSelectedIndex(0); } }
/** * Handle mouseDragged events. * * @param me The mouse event to process. * @see org.tigris.gef.base.ModeImpl#mouseDragged(java.awt.event.MouseEvent) */ public void mouseDragged(MouseEvent me) { if (dragFig != null) { me = editor.translateMouseEvent(me); Point newPoint = me.getPoint(); // Subtract the the offset of the click, to take account of user // having not initially clicked in the centre. newPoint.translate(-deltax, -deltay); PathItemPlacementStrategy pips = figEdge.getPathItemPlacementStrategy(dragFig); pips.setPoint(newPoint); newPoint = pips.getPoint(); int dx = newPoint.x - dragBasePoint.x; int dy = newPoint.y - dragBasePoint.y; dragBasePoint.setLocation(newPoint); dragFig.translate(dx, dy); me.consume(); editor.damaged(dragFig); } }
/* * @see org.tigris.gef.presentation.Fig#setBoundsImpl(int, int, int, int) */ @Override protected void setBoundsImpl(int x, int y, int w, int h) { int newW = w; int newH = h; int fw; int yy = y; for (Fig fig : (Collection<Fig>) getFigs()) { if (fig.isVisible() && fig != getBigPort()) { fw = fig.getMinimumSize().width; // set new bounds for all included figs fig.setBounds(x + 1, yy + 1, fw, fig.getMinimumSize().height); if (newW < fw + 2) { newW = fw + 2; } yy += fig.getMinimumSize().height; } } getBigPort().setBounds(x, y, newW, newH); calcBounds(); }
/** * On mouse release add the elements to the diagram * * @param me the mouse event */ @Override public void mouseReleased(final MouseEvent me) { if (me.isConsumed()) { if (LOG.isDebugEnabled()) { LOG.debug("MouseReleased but rejected as already consumed"); } return; } // TODO: Use per-project undo manager, not global UndoManager.getInstance().addMementoLock(this); start(); MutableGraphModel gm = (MutableGraphModel) editor.getGraphModel(); final int x = me.getX(); final int y = me.getY(); editor.damageAll(); final Point snapPt = new Point(x, y); editor.snap(snapPt); editor.damageAll(); int count = 0; Layer lay = editor.getLayerManager().getActiveLayer(); GraphNodeRenderer renderer = editor.getGraphNodeRenderer(); final List<FigNode> placedFigs = new ArrayList<FigNode>(modelElements.size()); ArgoDiagram diag = DiagramUtils.getActiveDiagram(); if (diag instanceof UMLDiagram) { for (final Object node : modelElements) { if (((UMLDiagram) diag).doesAccept(node)) { final FigNode pers = renderer.getFigNodeFor(gm, lay, node, null); pers.setLocation(snapPt.x + (count++ * 100), snapPt.y); if (LOG.isDebugEnabled()) { LOG.debug("mouseMoved: Location set (" + pers.getX() + "," + pers.getY() + ")"); } // TODO: Use per-project undo manager, not global UndoManager.getInstance().startChain(); editor.add(pers); gm.addNode(node); if (addRelatedEdges) { gm.addNodeRelatedEdges(node); } Fig encloser = null; final Rectangle bbox = pers.getBounds(); final List<Fig> otherFigs = lay.getContents(); for (final Fig otherFig : otherFigs) { if (!(otherFig.getUseTrapRect())) { continue; } if (!(otherFig instanceof FigNode)) { continue; } if (!otherFig.isVisible()) { continue; } if (otherFig.equals(pers)) { continue; } final Rectangle trap = otherFig.getTrapRect(); if (trap != null && trap.contains(bbox.x, bbox.y) && trap.contains(bbox.x + bbox.width, bbox.y + bbox.height)) { encloser = otherFig; } } pers.setEnclosingFig(encloser); placedFigs.add(pers); } } } // TODO: Use per-project undo manager, not global UndoManager.getInstance().removeMementoLock(this); if (UndoManager.getInstance().isGenerateMementos()) { AddToDiagramMemento memento = new AddToDiagramMemento(editor, placedFigs); UndoManager.getInstance().addMemento(memento); } UndoManager.getInstance().addMementoLock(this); editor.getSelectionManager().select(placedFigs); done(); me.consume(); }
/** * Makes sure that the edges stick to the outline of the fig. * * @see org.tigris.gef.presentation.Fig#getGravityPoints() */ @Override public List getGravityPoints() { return parent.getGravityPoints(); }