1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package org.devaki.nextobjects.workspace.models.graphics;
16 import java.io.Serializable;
17 import java.awt.Dimension;
18 import java.awt.Rectangle;
19 import java.awt.Graphics;
20 import java.awt.Point;
21 import java.awt.Polygon;
22 import org.devaki.nextobjects.util.NOGraphicsUtil;
23 import org.devaki.nextobjects.workspace.models.objects.BaseLine;
24 import org.devaki.nextobjects.workspace.models.objects.BaseObject;
25 import org.devaki.nextobjects.workspace.models.styles.LineStyle;
26 /***
27 * This class is responsible for drawing all line-like objects
28 *
29 * @author <a href="mailto:eflorent@devaki.org">Emmanuel Florent</a>
30 * @created December 22, 2003
31 */
32 public abstract class LineView extends ObjectView implements Serializable
33 {
34 /*** The style */
35 protected LineStyle myStyle;
36
37
38 /***
39 * Create a new instance of LineView
40 *
41 * @param pObject the context object
42 */
43 public LineView(BaseObject pObject)
44 {
45 super(pObject);
46 selectionPoints = new SelectionPoint[2];
47 this.myObject = pObject;
48 for (int i = 0; i < 2; i++)
49 {
50 selectionPoints[i] = new SelectionPoint(0, 0);
51 }
52 this.myStyle = new LineStyle(this);
53 }
54
55
56 /***
57 * Paint selection around the object
58 *
59 * @param g Graphic axis of the main view
60 */
61 public void renderSelected(Graphics g)
62 {
63 for (int i = 0; i < getSelectionPoints().length; i++)
64 {
65 this.getSelectionPoint(i).paint(g);
66 }
67 if (actionPoint != null && actionPoint.x != 0)
68 {
69 if (NOGraphicsUtil.distance(this.getSelectionPoint(0).getPoint(), actionPoint)
70 < NOGraphicsUtil.distance(
71 this.getSelectionPoint(1).getPoint(),
72 actionPoint))
73 {
74 g.drawLine(
75 this.getSelectionPoint(1).getPoint().x,
76 this.getSelectionPoint(1).getPoint().y,
77 this.actionPoint.x,
78 this.actionPoint.y);
79 }
80 else
81 {
82 g.drawLine(
83 this.getSelectionPoint(0).getPoint().x,
84 this.getSelectionPoint(0).getPoint().y,
85 this.actionPoint.x,
86 this.actionPoint.y);
87 }
88 }
89 }
90
91
92 /***
93 * Return the location This is ambiguous for a line but we provide graphic
94 * context as a smallest rectangle containig the line...
95 *
96 * @return the smallest rectangle location
97 */
98 public Point getLocation()
99 {
100 Rectangle r =
101 new Rectangle(
102 Math.min(
103 selectionPoints[0].getPoint().x,
104 selectionPoints[1].getPoint().x),
105 Math.min(
106 selectionPoints[0].getPoint().y,
107 selectionPoints[1].getPoint().y),
108 Math.max(
109 selectionPoints[0].getPoint().x,
110 selectionPoints[1].getPoint().x)
111 - Math.min(
112 selectionPoints[0].getPoint().x,
113 selectionPoints[1].getPoint().x),
114 Math.max(
115 selectionPoints[0].getPoint().y,
116 selectionPoints[1].getPoint().y)
117 - Math.min(
118 selectionPoints[0].getPoint().y,
119 selectionPoints[1].getPoint().y));
120
121 return r.getLocation();
122 }
123
124
125 /***
126 * Get the closest SelectionPoint.
127 *
128 * @param pPoint the pointed point
129 * @return the closest SelectionPoint
130 */
131 public Point getSelectionPoint(Point pPoint)
132 {
133 if (NOGraphicsUtil.distance(selectionPoints[0].getPoint(), pPoint)
134 < NOGraphicsUtil.distance(selectionPoints[1].getPoint(), pPoint))
135 {
136 return selectionPoints[0].getPoint();
137 }
138 else
139 {
140 return selectionPoints[1].getPoint();
141 }
142 }
143
144
145 /***
146 * Set the Location
147 *
148 * @param p the location
149 */
150 public void setLocation(Point p)
151 {
152 computeBestPoints(p);
153 }
154
155
156 /***
157 * Return the size This is ambiguous for a line but we provide graphic
158 * context as a smallest rectangle containig the line...
159 *
160 * @return the dimension
161 */
162 public Dimension getSize()
163 {
164 Rectangle r =
165 new Rectangle(
166 Math.min(
167 selectionPoints[0].getPoint().x,
168 selectionPoints[1].getPoint().x),
169 Math.min(
170 selectionPoints[0].getPoint().y,
171 selectionPoints[1].getPoint().y),
172 Math.max(
173 selectionPoints[0].getPoint().x,
174 selectionPoints[1].getPoint().x)
175 - Math.min(
176 selectionPoints[0].getPoint().x,
177 selectionPoints[1].getPoint().x),
178 Math.max(
179 selectionPoints[0].getPoint().y,
180 selectionPoints[1].getPoint().y)
181 - Math.min(
182 selectionPoints[0].getPoint().y,
183 selectionPoints[1].getPoint().y));
184
185 return r.getSize();
186 }
187
188
189 /***
190 * Set the size
191 *
192 * @param pDimension the dimension
193 */
194 public void setSize(Dimension pDimension)
195 {
196 }
197
198
199 /***
200 * Return the surface on which the user can click to select the object
201 *
202 * @return the surface as polygon/shape
203 */
204 public abstract Polygon getSurface();
205
206
207
208
209 /***
210 * Get the parent class control point
211 *
212 * @return the parent selection point
213 */
214 public SelectionPoint getParentClassPoint()
215 {
216 return selectionPoints[0];
217 }
218
219
220 /***
221 * Get the child class control point
222 *
223 * @return the child selection point
224 */
225 public SelectionPoint getChildClassPoint()
226 {
227 return selectionPoints[1];
228 }
229
230
231 /***
232 * Set the parent class control point
233 *
234 * @param pSelectionPoint the selection point
235 */
236 public void setParentClassPoint(SelectionPoint pSelectionPoint)
237 {
238 selectionPoints[0] = pSelectionPoint;
239 }
240
241
242 /***
243 * Set the child class control point
244 *
245 * @param pSelectionPoint the selection point
246 */
247 public void setChildClassPoint(SelectionPoint pSelectionPoint)
248 {
249 selectionPoints[1] = pSelectionPoint;
250 }
251
252
253 /***
254 * Get the style
255 *
256 * @return the style object
257 */
258 public LineStyle getStyle()
259 {
260 return this.myStyle;
261 }
262
263
264 /***
265 * Define the style
266 *
267 * @param pStyle the style
268 */
269 public void setStyle(LineStyle pStyle)
270 {
271 this.myStyle = pStyle;
272 }
273
274
275 /***
276 * Compute the best point (North -S-E-W , ...) to use for drawing the line
277 */
278 public void computeBestPoints()
279 {
280 Point p =
281 NOGraphicsUtil.getMiddle(
282 ((ClassView) ((BaseLine) myObject)
283 .getParentClass()
284 .getObjectView())
285 .getMiddlePoint(),
286 ((ClassView) ((BaseLine) myObject)
287 .getChildClass()
288 .getObjectView())
289 .getMiddlePoint());
290
291 computeBestPointsRight(p);
292 computeBestPointsLeft(p);
293 }
294
295
296 /***
297 * set the position ( N,S,E,W,NE,...) of the selection point for the point
298 * local to the line (parent class) This method is used during
299 * (de)serialization
300 *
301 * @param pPosition
302 * @see org.devaki.nextobjects.workspace.models.graphics.SelectionPoint
303 */
304 public void setLocalPosition(int pPosition)
305 {
306 selectionPoints[0] =
307 ((BaseLine) myObject)
308 .getParentClass()
309 .getObjectView()
310 .getSelectionPoint(
311 pPosition);
312 }
313
314
315 /***
316 * set the position ( N,S,E,W,NE,...) of the selection point for the point
317 * foreign to the line (child class) This method is used during
318 * (de)serialization
319 *
320 * @param pPosition
321 * @see org.devaki.nextobjects.workspace.models.graphics.SelectionPoint
322 */
323 public void setForeignPosition(int pPosition)
324 {
325 selectionPoints[1] =
326 ((BaseLine) myObject)
327 .getChildClass()
328 .getObjectView()
329 .getSelectionPoint(
330 pPosition);
331 }
332
333
334 /***
335 * Get the position ( N,S,E,W,NE,...) of the selection point for the point
336 * local to the line (parent class) This method is used during
337 * (de)serialization
338 *
339 * @return the north
340 * @see org.devaki.nextobjects.workspace.models.graphics.SelectionPoint
341 */
342 public int getLocalPosition()
343 {
344 int i;
345 int j = 0;
346
347 for (i = 0;
348 i
349 < ((BaseLine) myObject)
350 .getChildClass()
351 .getObjectView()
352 .getSelectionPoints()
353 .length;
354 i++)
355 {
356 if (selectionPoints[0]
357 .equals(
358 ((BaseLine) myObject)
359 .getParentClass()
360 .getObjectView()
361 .getSelectionPoint(
362 i)))
363 {
364 j = i;
365 }
366 }
367 return j;
368 }
369
370
371 /***
372 * Get the position ( N,S,E,W,NE,...) of the selection point for the point
373 * foreign to the line (child class) This method is used during
374 * (de)serialization
375 *
376 * @return the north
377 * @see org.devaki.nextobjects.workspace.models.graphics.SelectionPoint
378 */
379 public int getForeignPosition()
380 {
381 int i;
382 int j = 0;
383
384 for (i = 0;
385 i
386 < ((BaseLine) myObject)
387 .getChildClass()
388 .getObjectView()
389 .getSelectionPoints()
390 .length;
391 i++)
392 {
393 if (selectionPoints[1]
394 .equals(
395 ((BaseLine) myObject)
396 .getChildClass()
397 .getObjectView()
398 .getSelectionPoint(
399 i)))
400 {
401 j = i;
402 }
403 }
404 return j;
405 }
406
407
408 /***
409 * Compute the best points for a mouse click
410 *
411 * @param p1 the clicked point
412 */
413 private void computeBestPointsLeft(Point p1)
414 {
415 SelectionPoint bestEntityPoint = new SelectionPoint(0, 0);
416 int distance = 0;
417 int minValue = 2147483647;
418
419
420
421 for (int i = 0; i <= 7; i++)
422 {
423 Point p2 =
424 ((BaseLine) myObject)
425 .getChildClass()
426 .getObjectView()
427 .getSelectionPoint(i)
428 .getPoint();
429
430 distance = NOGraphicsUtil.distance(p1, p2);
431 if (distance < minValue)
432 {
433 minValue = distance;
434 bestEntityPoint =
435 ((BaseLine) myObject)
436 .getChildClass()
437 .getObjectView()
438 .getSelectionPoint(
439 i);
440 }
441 }
442 selectionPoints[1] = bestEntityPoint;
443 }
444
445
446 /***
447 * Compute the best point for a click
448 *
449 * @param p1 the clicked point
450 */
451 private void computeBestPointsRight(Point p1)
452 {
453 int minValue = 2147483647;
454
455 int distance = 0;
456
457 SelectionPoint bestAssociationPoint = new SelectionPoint(0, 0);
458
459 for (int i = 0; i <= 7; i++)
460 {
461 Point p2 =
462 ((BaseLine) myObject)
463 .getParentClass()
464 .getObjectView()
465 .getSelectionPoint(i)
466 .getPoint();
467
468 distance = NOGraphicsUtil.distance(p1, p2);
469 if (distance < minValue)
470 {
471 minValue = distance;
472 bestAssociationPoint =
473 ((BaseLine) myObject)
474 .getParentClass()
475 .getObjectView()
476 .getSelectionPoint(
477 i);
478 }
479 }
480 selectionPoints[0] = bestAssociationPoint;
481 }
482
483
484 /***
485 * Compute the best point for a given mouse click.
486 *
487 * @param p1 the clicked point
488 */
489 public void computeBestPoints(Point p1)
490 {
491 Point p2 =
492 ((ClassView) ((BaseLine) myObject).getParentClass().getObjectView())
493 .getMiddlePoint();
494 Point p3 =
495 ((ClassView) ((BaseLine) myObject).getChildClass().getObjectView())
496 .getMiddlePoint();
497
498 if (NOGraphicsUtil.distance(p1, p2) > NOGraphicsUtil.distance(p1, p3))
499 {
500 computeBestPointsLeft(p1);
501 }
502 else
503 {
504 computeBestPointsRight(p1);
505 }
506 }
507 }