001: /*
002: * The contents of this file are subject to the
003: * Mozilla Public License Version 1.1 (the "License");
004: * you may not use this file except in compliance with the License.
005: * You may obtain a copy of the License at http://www.mozilla.org/MPL/
006: *
007: * Software distributed under the License is distributed on an "AS IS"
008: * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.
009: * See the License for the specific language governing rights and
010: * limitations under the License.
011: *
012: * The Initial Developer of the Original Code is Simulacra Media Ltd.
013: * Portions created by Simulacra Media Ltd are Copyright (C) Simulacra Media Ltd, 2004.
014: *
015: * All Rights Reserved.
016: *
017: * Contributor(s):
018: */
019: package org.openharmonise.workfloweditor.flowchart;
020:
021: import java.awt.*;
022: import java.awt.geom.*;
023: import java.util.*;
024: import java.util.List;
025:
026: import javax.swing.*;
027:
028: import org.openharmonise.workfloweditor.*;
029: import org.openharmonise.workfloweditor.flowchart.shapes.*;
030: import org.openharmonise.workfloweditor.model.*;
031: import org.openharmonise.workfloweditor.vfs.*;
032:
033: /**
034: * The workflow diagram.
035: *
036: * @author Matthew Large
037: * @version $Revision: 1.1 $
038: *
039: */
040: public class FlowChart extends JComponent {
041:
042: /**
043: * List of all the {@link AbstractWorkflowShape} objects in the diagram.
044: */
045: private ArrayList m_shapes = new ArrayList();
046:
047: /**
048: * The model that this diagram represents.
049: */
050: private WorkflowModel m_model = null;
051:
052: /**
053: * List of all the {@link StageShape} objects in the diagram.
054: */
055: private ArrayList m_stages = new ArrayList();
056:
057: /**
058: * Map of end {@link StageShape} object to a list of {@link ConnectionLine} objects.
059: */
060: private HashMap m_lines = new HashMap();
061:
062: /**
063: * List of {@link AbstractWorkflowShape} objects to be displayed temporarily.
064: */
065: private ArrayList m_tempShapes = new ArrayList();
066:
067: /**
068: *
069: */
070: public FlowChart() {
071: super ();
072: this .setup();
073: }
074:
075: /**
076: * Configures the flow chart.
077: *
078: */
079: private void setup() {
080: MoveMouseHandler moveHandler = new MoveMouseHandler(this );
081: this .addMouseListener(moveHandler);
082: this .addMouseMotionListener(moveHandler);
083:
084: ConnectMouseHandler connectHandler = new ConnectMouseHandler(
085: this );
086: this .addMouseListener(connectHandler);
087: this .addMouseMotionListener(connectHandler);
088:
089: LineSelectionMouseHandler lineHandler = new LineSelectionMouseHandler(
090: this );
091: this .addMouseListener(lineHandler);
092: this .addMouseMotionListener(lineHandler);
093:
094: AttributeMouseHandler attHandler = new AttributeMouseHandler(
095: this );
096: this .addMouseListener(attHandler);
097: this .addMouseMotionListener(attHandler);
098: this .repaint();
099: }
100:
101: /* (non-Javadoc)
102: * @see java.awt.Component#paint(java.awt.Graphics)
103: */
104: public void paint(Graphics g) {
105: Graphics2D g2D = (Graphics2D) g;
106: g2D.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
107: RenderingHints.VALUE_ANTIALIAS_ON);
108: g2D.setPaint(new Color(173, 169, 143));
109: g2D.fillRect(0, 0, this .getWidth(), this .getHeight());
110:
111: for (int i = this .m_stages.size() - 1; i >= 0; i--) {
112: StageShape stage = (StageShape) this .m_stages.get(i);
113: stage.draw(g2D);
114: if (this .m_lines.get(stage) != null) {
115: ArrayList lines = ((ArrayList) this .m_lines.get(stage));
116: for (int j = lines.size() - 1; j >= 0; j--) {
117: ConnectionLine line = (ConnectionLine) lines.get(j);
118: line.draw(g2D);
119: }
120: }
121: }
122: Iterator itor = this .m_tempShapes.iterator();
123: while (itor.hasNext()) {
124: AbstractWorkflowShape shape = (AbstractWorkflowShape) itor
125: .next();
126: shape.draw(g2D);
127: }
128: }
129:
130: /**
131: * Adds a shapes to be displayed temporarily.
132: *
133: * @param shape Shape to add
134: */
135: public void addTempShape(AbstractWorkflowShape shape) {
136: this .m_tempShapes.add(shape);
137: }
138:
139: /**
140: * Removes a shape that was added to be displayed temporarily.
141: *
142: * @param shape Shape to be removed
143: */
144: public void removeTempShape(AbstractWorkflowShape shape) {
145: this .m_tempShapes.remove(shape);
146: }
147:
148: /**
149: * Returns a list of all the shapes in the diagram.
150: *
151: * @return List of {@link AbstractWorkflowShape} objects
152: */
153: public List getShapes() {
154: return (List) this .m_shapes.clone();
155: }
156:
157: /**
158: * Adds a shape to the diagram.
159: *
160: * @param shape Shape to add
161: */
162: public void addShape(AbstractWorkflowShape shape) {
163: this .m_shapes.add(shape);
164: this .indexShapes();
165: }
166:
167: /**
168: * Removes a shape from the diagram.
169: *
170: * @param shape Shape to remove
171: */
172: public void removeShape(AbstractWorkflowShape shape) {
173: if (shape instanceof StageShape) {
174: StageShape stageShape = (StageShape) shape;
175: Iterator itor = this .getShapes().iterator();
176: while (itor.hasNext()) {
177: AbstractWorkflowShape shape2 = (AbstractWorkflowShape) itor
178: .next();
179: if (shape2 instanceof ConnectionLine) {
180: ConnectionLine line = (ConnectionLine) shape2;
181: if (line.getStartShape() == stageShape) {
182: this .removeShape(line);
183: }
184: if (line.getEndShape() == stageShape) {
185: this .removeShape(line);
186: }
187: }
188: }
189: itor = stageShape.getDependancies().iterator();
190: while (itor.hasNext()) {
191: StageShape dependancy = (StageShape) itor.next();
192: stageShape.removeDependancy(dependancy);
193: }
194:
195: } else if (shape instanceof ConnectionLine) {
196: ConnectionLine line = (ConnectionLine) shape;
197: if (line.getEndShape() != null
198: && line.getStartShape() != null) {
199: line.getEndShape().removeDependancy(
200: line.getStartShape());
201: }
202: }
203: this .m_shapes.remove(shape);
204: this .indexShapes();
205: }
206:
207: /**
208: * Returns the model that this diagram represents.
209: *
210: * @return Model
211: */
212: public WorkflowModel getModel() {
213: return this .m_model;
214: }
215:
216: /**
217: * Sets the model that this diagram should represent.
218: *
219: * @param model Model
220: */
221: public void setModel(WorkflowModel model) {
222: this .m_model = model;
223:
224: int nYpos = 10;
225:
226: Iterator itor = model.getWorkflowStages().iterator();
227: while (itor.hasNext()) {
228: VFSWorkflowStage stage = (VFSWorkflowStage) itor.next();
229: String sWorkflowPath = ((VFSWorkflowModel) model)
230: .getStagesCollection().getFullPath();
231: String sStagePath = stage.getPath();
232:
233: int nXtemp = 10;
234: int nYtemp = nYpos;
235:
236: Point2D.Float point = WorkflowLayoutStore.getInstance()
237: .getStageLayout(sWorkflowPath, sStagePath);
238: if (point != null) {
239: nXtemp = new Float(point.x).intValue();
240: nYtemp = new Float(point.y).intValue();
241: }
242:
243: StageShape stageShape = new StageShape(nXtemp, nYtemp,
244: stage);
245: this .m_shapes.add(stageShape);
246:
247: nYpos = nYpos + 120;
248: }
249:
250: itor = model.getWorkflowStages().iterator();
251: while (itor.hasNext()) {
252: WorkflowStage stage = (WorkflowStage) itor.next();
253: Iterator dependItor = stage.getDependancies().iterator();
254: while (dependItor.hasNext()) {
255: WorkflowStage dependStage = (WorkflowStage) dependItor
256: .next();
257:
258: StageShape startShape = null;
259: StageShape endShape = null;
260: Iterator itor2 = this .m_shapes.iterator();
261: while (itor2.hasNext()) {
262: AbstractWorkflowShape shape = (AbstractWorkflowShape) itor2
263: .next();
264: if (shape instanceof StageShape
265: && ((StageShape) shape).getStage() == dependStage) {
266: startShape = (StageShape) shape;
267: } else if (shape instanceof StageShape
268: && ((StageShape) shape).getStage() == stage) {
269: endShape = (StageShape) shape;
270: }
271: }
272: if (startShape != null && endShape != null) {
273: ConnectionLine connection = new ConnectionLine(10,
274: 10);
275: connection.setStartShape(startShape);
276: connection.setEndShape(endShape);
277: this .m_shapes.add(connection);
278: }
279: }
280: }
281: this .indexShapes();
282: }
283:
284: /**
285: * Indexes the shapes in the diagram, applying appropriate layering
286: * to them.
287: *
288: */
289: private void indexShapes() {
290: this .m_stages.clear();
291: this .m_lines.clear();
292:
293: Iterator itor = this .m_shapes.iterator();
294: while (itor.hasNext()) {
295: AbstractWorkflowShape shape = (AbstractWorkflowShape) itor
296: .next();
297: if (shape instanceof StageShape) {
298: if (!this .m_stages.contains(shape)) {
299: this .m_stages.add(shape);
300: }
301: Iterator itor2 = ((StageShape) shape).getDependancies()
302: .iterator();
303: while (itor2.hasNext()) {
304: StageShape dependStage = (StageShape) itor2.next();
305: if (!this .m_stages.contains(dependStage)) {
306: this .m_stages.add(0, dependStage);
307: } else if (this .m_stages.indexOf(dependStage) > this .m_stages
308: .indexOf(shape)) {
309: this .m_stages.remove(dependStage);
310: this .m_stages.add(this .m_stages.indexOf(shape),
311: dependStage);
312: }
313: }
314: } else if (shape instanceof ConnectionLine) {
315: StageShape endStage = ((ConnectionLine) shape)
316: .getEndShape();
317: if (!this .m_lines.keySet().contains(endStage)) {
318: ArrayList lines = new ArrayList();
319: lines.add(shape);
320: this .m_lines.put(endStage, lines);
321: } else {
322: ArrayList lines = (ArrayList) this .m_lines
323: .get(endStage);
324: lines.add(shape);
325: }
326: }
327: }
328:
329: this .m_shapes.clear();
330: for (int i = this .m_stages.size() - 1; i >= 0; i--) {
331: StageShape stage = (StageShape) this .m_stages.get(i);
332: this .m_shapes.add(0, stage);
333: if (this .m_lines.get(stage) != null) {
334: ArrayList lines = ((ArrayList) this .m_lines.get(stage));
335: for (int j = lines.size() - 1; j >= 0; j--) {
336: ConnectionLine line = (ConnectionLine) lines.get(j);
337: this .m_shapes.add(0, line);
338: }
339: }
340: }
341:
342: this.paintImmediately(this.getBounds());
343: }
344:
345: }
|