View Javadoc

1   /*
2    *  nextobjects Copyright (C) 2001-2005 Emmanuel Florent
3    *  This program is free software; you can redistribute it and/or modify
4    *  it under the terms of the GNU General Public License as published by the
5    *  Free Software Foundation; either version 2 of the License, or (at your
6    *  option) any later version.
7    *  This program is distributed in the hope that it will
8    *  be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
9    *  of MERCHANTABILITY or FITNESS FOR A PARTICULAR
10   *  PURPOSE. See the GNU General Public License for more details.
11   *  You should have received a copy of the GNU General Public License along
12   *  with this program; if not, write to the Free Software Foundation, Inc., 59
13   *  Temple Place - Suite 330, Boston, MA 02111-1307, USA.
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         // initialize to max ...
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     // initialize to max ...
455     int distance = 0;
456     //idem
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 }