001: // THIS SOFTWARE IS PROVIDED BY SOFTARIS PTY.LTD. AND OTHER METABOSS
002: // CONTRIBUTORS ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING,
003: // BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
004: // FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SOFTARIS PTY.LTD.
005: // OR OTHER METABOSS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
006: // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
007: // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
008: // OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
009: // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
010: // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
011: // EVEN IF SOFTARIS PTY.LTD. OR OTHER METABOSS CONTRIBUTORS ARE ADVISED OF THE
012: // POSSIBILITY OF SUCH DAMAGE.
013: //
014: // Copyright 2000-2005 © Softaris Pty.Ltd. All Rights Reserved.
015: package com.metaboss.applications.designstudio.components;
016:
017: import java.awt.Color;
018: import java.awt.Graphics;
019: import java.awt.Point;
020: import java.awt.Rectangle;
021: import java.awt.event.KeyEvent;
022: import java.awt.event.MouseEvent;
023: import java.awt.geom.Rectangle2D;
024: import java.util.ArrayList;
025: import java.util.Hashtable;
026: import java.util.Map;
027:
028: import javax.swing.SwingUtilities;
029:
030: import org.jgraph.JGraph;
031: import org.jgraph.graph.CellMapper;
032: import org.jgraph.graph.CellView;
033: import org.jgraph.graph.DefaultGraphCell;
034: import org.jgraph.graph.DefaultPort;
035: import org.jgraph.graph.Edge;
036: import org.jgraph.graph.EdgeView;
037: import org.jgraph.graph.GraphCell;
038: import org.jgraph.graph.GraphConstants;
039: import org.jgraph.graph.GraphModel;
040: import org.jgraph.graph.VertexView;
041: import org.jgraph.plaf.GraphUI;
042: import org.jgraph.plaf.basic.BasicGraphUI;
043:
044: import com.metaboss.applications.designstudio.Application;
045: import com.metaboss.applications.designstudio.BaseGraphModel;
046: import com.metaboss.applications.designstudio.BaseUserObject;
047:
048: /* Base Graph class */
049:
050: public class DesignGraph extends JGraph {
051: protected boolean mShowEdgesLabels = true;
052: protected boolean mShowEdgesCardinalities = false;
053: protected boolean mShowEdgesEndsNames = false;
054: protected boolean mShowClassVertex = true;
055: protected boolean mShowVertexFields = true;
056: protected boolean mVertexHaveFields = false;
057: protected int mUpdateCount = 0;
058:
059: public DesignGraph(GraphModel pModel) {
060: super (pModel);
061:
062: loadGraphProperties();
063: setLockedHandleColor(Color.green);
064: setGridColor(Color.lightGray);
065: setBendable(true);
066: setAntiAliased(true);
067: }
068:
069: // load graph properties from application settings
070: public void loadGraphProperties() {
071: beginUpdate();
072: try {
073: setGridEnabled(Application.properties.mUseGrid);
074: setGridVisible(Application.properties.mShowGrid);
075: setPortsVisible(Application.properties.mPortsVisible);
076: setShowEdgesLabels(Application.properties.mShowEdgesLabels);
077: setShowEdgesCardinalities(Application.properties.mShowEdgesCardinality);
078: setShowEdgesEndsNames(Application.properties.mShowEdgesEndsNames);
079: } finally {
080: stopUpdate();
081: }
082: }
083:
084: // get tooltip
085: public String getToolTipText(MouseEvent event) {
086: if (event != null && Application.properties.mShowToolTip) {
087: DefaultGraphCell lCell = (DefaultGraphCell) getFirstCellForLocation(
088: event.getX(), event.getY());
089: if (lCell != null) {
090: Object lCellUserObject = lCell.getUserObject();
091: try {
092: if (lCellUserObject != null
093: && lCellUserObject instanceof BaseUserObject)
094: return ((BaseUserObject) lCellUserObject)
095: .getToolTip();
096: } catch (Exception e) {
097: e.printStackTrace();
098: }
099: }
100: }
101: return null;
102: }
103:
104: public String convertValueToString(Object value) {
105: if (value instanceof EdgeView && !mShowEdgesLabels)
106: return null;
107: else
108: return super .convertValueToString(value);
109: }
110:
111: public void updateUI() {
112: setUI(new DomainGraphUI());
113: invalidate();
114: }
115:
116: public void paint(Graphics g) {
117: if (mUpdateCount > 0)
118: return;
119: super .paint(g);
120: }
121:
122: // hard update graph content
123: public void updateGraphContent() {
124: if (mUpdateCount > 0)
125: return;
126:
127: BaseGraphModel mModel = (BaseGraphModel) getModel();
128: if (mModel != null) {
129: mModel.setLoading(true);
130: try {
131: CellView[] views = graphLayoutCache.getRoots();
132: CellView[] all = graphLayoutCache
133: .getAllDescendants(views);
134: Map attributes = GraphConstants.createAttributes(all,
135: null);
136: getGraphLayoutCache()
137: .edit(attributes, null, null, null);
138: } finally {
139: mModel.setLoading(false);
140: }
141: }
142: }
143:
144: public void beginUpdate() {
145: mUpdateCount++;
146: }
147:
148: public void stopUpdate(boolean pUpdate) {
149: if (mUpdateCount > 0)
150: mUpdateCount--;
151: if (mUpdateCount == 0 && pUpdate)
152: updateGraphContent();
153: }
154:
155: public void stopUpdate() {
156: stopUpdate(true);
157: }
158:
159: protected VertexView createVertexView(JGraph graph, CellMapper cm,
160: Object v) {
161: if (v instanceof VertexCell)
162: return new VertexCellView(v, this , cm);
163: else
164: return super .createVertexView(graph, cm, v);
165: }
166:
167: protected EdgeView createEdgeView(JGraph graph, CellMapper mapper,
168: Object cell) {
169: //return super.createEdgeView(e, cm);
170: return new DesignEdgeView(cell, graph, mapper);
171: }
172:
173: protected void processMouseEvent(MouseEvent e) {
174: //???
175: if (SwingUtilities.isLeftMouseButton(e)
176: && e.getClickCount() == 2) {
177: DefaultGraphCell lCell = (DefaultGraphCell) getFirstCellForLocation(
178: e.getX(), e.getY());
179: if (lCell != null) {
180: try {
181: ((BaseUserObject) lCell.getUserObject())
182: .editObject();
183: } catch (Exception ex) {
184: Application.processError(ex);
185: }
186: return;
187: }
188: }
189: super .processMouseEvent(e);
190: }
191:
192: protected void processKeyEvent(KeyEvent e) {
193: if (e.getID() == KeyEvent.KEY_PRESSED) {
194: int lKeyCode = e.getKeyCode();
195: int lStep = (isGridEnabled() || e.isShiftDown()) ? (int) (getGridSize())
196: : 1;
197:
198: switch (lKeyCode) {
199: case KeyEvent.VK_LEFT:
200: if (moveVertex(-lStep, 0))
201: return;
202: break;
203: case KeyEvent.VK_RIGHT:
204: if (moveVertex(lStep, 0))
205: return;
206: break;
207: case KeyEvent.VK_UP:
208: if (moveVertex(0, -lStep))
209: return;
210: break;
211: case KeyEvent.VK_DOWN:
212: if (moveVertex(0, lStep))
213: return;
214: break;
215: }
216: }
217: super .processKeyEvent(e);
218: }
219:
220: // move current vertex left
221: protected boolean moveVertex(int x, int y) {
222: boolean lResult = false;
223: DefaultGraphCell lCell = (DefaultGraphCell) getSelectionCell();
224: if (lCell != null && lCell instanceof VertexCell) {
225: Map lViewMap = new Hashtable();
226:
227: Rectangle2D lRect = GraphConstants.getBounds(lCell
228: .getAttributes());
229: Point lPoint = new Point((int) lRect.getX(), (int) lRect
230: .getY());
231: lPoint.x += x;
232: lPoint.y += y;
233: Map lAttributes = GraphConstants.createMap();
234: GraphConstants
235: .setBounds(lAttributes, new Rectangle(lPoint));
236: lViewMap.put(lCell, lAttributes);
237:
238: getGraphLayoutCache().edit(lViewMap, null, null, null);
239: lResult = true;
240: }
241: return lResult;
242: }
243:
244: /* Properties */
245:
246: public boolean getShowEdgesLabels() {
247: return mShowEdgesLabels;
248: }
249:
250: public void setShowEdgesLabels(boolean pValue) {
251: if (mShowEdgesLabels != pValue) {
252: mShowEdgesLabels = pValue;
253: updateGraphContent();
254: }
255: }
256:
257: public boolean getShowEdgesEndsNames() {
258: return mShowEdgesEndsNames;
259: }
260:
261: public void setShowEdgesEndsNames(boolean pValue) {
262: if (mShowEdgesEndsNames != pValue) {
263: mShowEdgesEndsNames = pValue;
264: updateGraphContent();
265: }
266: }
267:
268: public boolean getShowEdgesCardinalities() {
269: return mShowEdgesCardinalities;
270: }
271:
272: public void setShowEdgesCardinalities(boolean pValue) {
273: if (mShowEdgesCardinalities != pValue) {
274: mShowEdgesCardinalities = pValue;
275: updateGraphContent();
276: }
277: }
278:
279: public boolean getShowClassVertex() {
280: return mShowClassVertex;
281: }
282:
283: public void setShowClassVertex(boolean pValue) {
284: if (mShowClassVertex != pValue) {
285: mShowClassVertex = pValue;
286: updateGraphContent();
287: }
288: }
289:
290: public boolean getShowVertexFields() {
291: return mShowVertexFields;
292: }
293:
294: public void setShowVertexFields(boolean pValue) {
295: if (mShowVertexFields != pValue) {
296: mShowVertexFields = pValue;
297: updateGraphContent();
298: }
299: }
300:
301: public boolean getVertexHaveFields() {
302: return mVertexHaveFields;
303: }
304:
305: public void setVertexHaveFields(boolean pValue) {
306: if (mVertexHaveFields != pValue) {
307: mVertexHaveFields = pValue;
308: updateGraphContent();
309: }
310: }
311:
312: public void setUI(GraphUI ui) {
313: super .setUI(ui);
314: }
315:
316: /* UI class */
317:
318: public class DomainGraphUI extends BasicGraphUI {
319: protected void paintGrid(double gs, Graphics g, Rectangle2D r) {
320: //super.paintGrid(arg0, arg1, arg2);
321:
322: Rectangle rr = (Rectangle) g.getClipBounds();
323: double xl = rr.x;
324: double yt = rr.y;
325: double xr = xl + rr.width;
326: double yb = yt + rr.height;
327: double sgs = (double) gs * graph.getScale();
328:
329: while (sgs < 20)
330: sgs *= 2;
331:
332: if (sgs >= 0.0) {
333:
334: int xs = (int) (Math.floor(xl / sgs) * sgs);
335: int xe = (int) (Math.ceil(xr / sgs) * sgs);
336: int ys = (int) (Math.floor(yt / sgs) * sgs);
337: int ye = (int) (Math.ceil(yb / sgs) * sgs);
338:
339: g.setColor(graph.getGridColor());
340:
341: xe += (int) Math.ceil(sgs);
342: ye += (int) Math.ceil(sgs);
343:
344: boolean lFlag = true;
345:
346: for (double x = xs; x <= xe; x += sgs) {
347: int ix = (int) Math.round(x);
348: if (lFlag) {
349: for (double y = ys; y <= ye; y += 2) {
350: int iy = (int) Math.round(y);
351: g.drawLine(ix, iy, ix, iy);
352: }
353: } else {
354: for (double y = ys; y <= ye; y += 10) {
355: int iy = (int) Math.round(y);
356: g.drawLine(ix, iy, ix, iy + 5);
357: }
358: }
359: lFlag = !lFlag;
360: }
361:
362: lFlag = true;
363: for (double y = ys; y <= ye; y += sgs) {
364: int iy = (int) Math.round(y);
365: if (lFlag) {
366: for (double x = xs; x <= xe; x += 2) {
367: int ix = (int) Math.round(x);
368: g.drawLine(ix, iy, ix, iy);
369: }
370: } else {
371: for (double x = xs; x <= xe; x += 10) {
372: int ix = (int) Math.round(x);
373: g.drawLine(ix, iy, ix + 5, iy);
374: }
375: }
376: lFlag = !lFlag;
377: }
378: }
379: }
380: }
381:
382: public Object[] getSelectionCells() {
383: //return super.getSelectionCells();
384:
385: Object[] lCells = super .getSelectionCells();
386: ArrayList lList = new ArrayList();
387: if (lCells != null) {
388: for (int i = 0; i < lCells.length; i++) {
389: GraphCell lCell = (GraphCell) lCells[i];
390: if (lCell instanceof VertexCell) {
391: VertexCell lVertex = (VertexCell) lCell;
392: Object[] lEdges = getConectedEdges(lVertex);
393: if (lEdges != null) {
394: for (int k = 0; k < lEdges.length; k++) {
395: lList.add(lEdges[k]);
396: }
397: }
398: }
399: lList.add(lCell);
400: }
401:
402: }
403: return lList.toArray();
404: }
405:
406: private Object[] getConectedEdges(VertexCell pVertex) {
407: ArrayList lList = new ArrayList();
408: if (pVertex != null) {
409: Object[] lRoots = getRoots();
410: if (lRoots != null) {
411: for (int i = 0; i < lRoots.length; i++) {
412: Object lObject = lRoots[i];
413: if (lObject instanceof Edge) {
414: Edge lEdge = (Edge) lObject;
415: Object lUserObject = pVertex.getUserObject();
416: if (lUserObject != null
417: && lEdge.getSource() != null
418: && lEdge.getTarget() != null) {
419: if (lUserObject.equals(((DefaultPort) lEdge
420: .getSource()).getUserObject())
421: && lUserObject
422: .equals(((DefaultPort) lEdge
423: .getTarget())
424: .getUserObject()))
425: lList.add(lEdge);
426: }
427: }
428: }
429: }
430: }
431: return lList.toArray();
432: }
433: }
|